diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f11819572b..57fabbc22a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -85,7 +85,7 @@ jobs: --recursive \ --configfile pyproject.toml \ --format custom \ - --msg-template '::error file={abspath},line={line},col={col},title=Bandit {test_id})::{msg}' \ + --msg-template '::error file={abspath},line={line},col={col},title=Bandit ({test_id})::{msg}' \ src/ 2> /dev/null - name: Static type checking diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e3668106d7..d00e73dde1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: exclude: .pre-commit-config.yaml - id: pt_structure - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.8.6 + rev: v0.9.2 hooks: - id: ruff args: [ "--fix" ] @@ -32,14 +32,14 @@ repos: - id: sass-lint files: '^src/.*\.scss' - repo: https://github.com/pre-commit/mirrors-eslint - rev: v9.17.0 + rev: v9.18.0 hooks: - id: eslint files: '^src/.*\.jsx?$' additional_dependencies: - eslint-react - repo: https://github.com/PyCQA/bandit - rev: 1.8.0 + rev: 1.8.2 hooks: - id: bandit args: ["-c", "pyproject.toml", "--quiet"] diff --git a/CHANGES.md b/CHANGES.md index c4643eedaf..90d7b44ab8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,8 +1,82 @@ # Changes +## 2025.1 + +`2025-01-09` | [4cbd81a1fe...db7d0c9304](https://github.com/OneGov/onegov-cloud/compare/4cbd81a1fe^...db7d0c9304) + +### Core + +##### Update stamp price + +`Feature` | [NONE](#NONE) | [e9bcdd74bc](https://github.com/onegov/onegov-cloud/commit/e9bcdd74bc4da984f533bde08d17e607f454d626) + +### Election Day + +##### Adds missing static entities for unit tests + +`Bugfix` | [NONE](#NONE) | [4cbd81a1fe](https://github.com/onegov/onegov-cloud/commit/4cbd81a1fecce0cf72a85082979017256f9fae88) + +### Electionday + +##### Adds municipality and map data for 2025 + +`Feature` | [OGC-1953](https://linear.app/onegovcloud/issue/OGC-1953) | [db7d0c9304](https://github.com/onegov/onegov-cloud/commit/db7d0c93044bbc02b257555a1dc8fd044af78e8c) + +### Org + +##### Adds optional ordering by filename or caption to image sets + +`Feature` | [OGC-2000](https://linear.app/onegovcloud/issue/OGC-2000) | [f67e97d4ed](https://github.com/onegov/onegov-cloud/commit/f67e97d4ed357dccaee3008bc58544504b22b02d) + +## test + +`2025-01-08` | [9c3aee5da3...bcfbf712a8](https://github.com/OneGov/onegov-cloud/compare/9c3aee5da3^...bcfbf712a8) + +### Core + +##### Add descriptions in formcode docs + +`Feature` | [OGC-1942](https://linear.app/onegovcloud/issue/OGC-1942) | [6908b4cf33](https://github.com/onegov/onegov-cloud/commit/6908b4cf33cdf05552da1056b87d03f645b688b8) + +### Landsgemeinde + +##### Remove "Auskunft" from Footer + +`Feature` | [OGC-1991](https://linear.app/onegovcloud/issue/OGC-1991) | [675267da50](https://github.com/onegov/onegov-cloud/commit/675267da50dc7ee3968a96c8feb7fa76abf519ab) + +##### Rename Archive + +`Feature` | [OGC-1990](https://linear.app/onegovcloud/issue/OGC-1990) | [ee62c7a0c9](https://github.com/onegov/onegov-cloud/commit/ee62c7a0c915845d604adcc8ab0e539ca26cdd50) + +##### Prevent crash on file replacement + +`Bugfix` | [OGC-1999](https://linear.app/onegovcloud/issue/OGC-1999) | [eb0b55a269](https://github.com/onegov/onegov-cloud/commit/eb0b55a269f1cd0967615027dfd1a7cbf2f70f36) + +##### File Upload View + +`Bugfix` | [OGC-1998](https://linear.app/onegovcloud/issue/OGC-1998) | [95e4fb151e](https://github.com/onegov/onegov-cloud/commit/95e4fb151e53671ac667940d31a9dd019d97ef9e) + +### Settings + +##### Displays the web statistics url + +`Feature` | [OGC-1639](https://linear.app/onegovcloud/issue/OGC-1639) | [13baf032fd](https://github.com/onegov/onegov-cloud/commit/13baf032fd10932908cc089f192b2cb12c0c6fe0) + +### Town 6 + +##### Search View + +`Feature` | [OGC-1966](https://linear.app/onegovcloud/issue/OGC-1966) | [c080567c8e](https://github.com/onegov/onegov-cloud/commit/c080567c8ed2d2e13e277e2689db56e5fb6ef974) + +### User + +##### Fixes various issues in OIDC authentication provider + +`Bugfix` | [OGC-1767](https://linear.app/onegovcloud/issue/OGC-1767) | [bef47625f0](https://github.com/onegov/onegov-cloud/commit/bef47625f02b602e040449cdd2534619bf595ddb) + ## 2024.60 -`2024-12-19` | [5925b224b9...947c48974f](https://github.com/OneGov/onegov-cloud/compare/5925b224b9^...947c48974f) +`2024-12-19` | [5925b224b9...7bff3ede2e](https://github.com/OneGov/onegov-cloud/compare/5925b224b9^...7bff3ede2e) **Upgrade hints** - On the off-chance that we have some duplicate `Payment` associations this upgrade task will fail, in which case we would need to write another migration to remove duplicates for all links on `Payment`. @@ -2142,94 +2216,3 @@ Feature `Bugfix` | [8a532a45af](https://github.com/onegov/onegov-cloud/commit/8a532a45afa8a159819e63d08d5d1ebf2df070d2) -## 2024.15 - -`2024-03-15` | [c5e23a0e51...2fd12fd218](https://github.com/OneGov/onegov-cloud/compare/c5e23a0e51^...2fd12fd218) - -### File - -##### Adds compatibility with filedepot 0.11. - -`Feature` | [OGC-1480](https://linear.app/onegovcloud/issue/OGC-1480) | [9efea02b1b](https://github.com/onegov/onegov-cloud/commit/9efea02b1bf0b6a30a13f807b7d379398c29b87e) - -### Form - -##### Add a select field which translates the choice labels. - -`Feature` | [OGC-1518](https://linear.app/onegovcloud/issue/OGC-1518) | [cf68edb7ec](https://github.com/onegov/onegov-cloud/commit/cf68edb7ec1e3a018746174a8acf58685ca0eff1) - -### Gis - -##### Adds a geolocation button to the map input - -`Feature` | [OGC-1513](https://linear.app/onegovcloud/issue/OGC-1513) | [572406c6ad](https://github.com/onegov/onegov-cloud/commit/572406c6adf9cb6d851c8a26259f1cdde42891fc) - -### Org - -##### Add Option for links in side-panel - -`Feature` | [OGC-1321](https://linear.app/onegovcloud/issue/OGC-1321) | [bc29f9d879](https://github.com/onegov/onegov-cloud/commit/bc29f9d8799c843895697e915fdd70efa8c0ab82) - -##### Fix missing translations for files in sidebar option - -`Bugfix` | [OGC-1500](https://linear.app/onegovcloud/issue/OGC-1500) | [eac0af05b0](https://github.com/onegov/onegov-cloud/commit/eac0af05b0ba36c565de8587d7e1809233856c70) - -##### Fix message so iOS can autofill - -`Bugfix` | [OGC-1415](https://linear.app/onegovcloud/issue/OGC-1415) | [1e08464519](https://github.com/onegov/onegov-cloud/commit/1e08464519e3346eb9328f99ddbca46393b5166c) - -##### Sort photo albums by newest first. - -`Bugfix` | [OGC-1452](https://linear.app/onegovcloud/issue/OGC-1452) | [3ab63eb00e](https://github.com/onegov/onegov-cloud/commit/3ab63eb00e6960acfaa0b97480937d633d0fafbe) - -##### Implement logic to prevent premature archiving of reservations. - -Imagine a reservation made a year in advance (which happens in practice) -After a year, `ticket.last_change` would indicate it shall be archived. -However, some reservations of this ticket might be fairly recent, like a -month ago. Therefore it is a bit premature to be considered for archive. - -`Bugfix` | [OGC-1481](https://linear.app/onegovcloud/issue/OGC-1481) | [9a8da1bca0](https://github.com/onegov/onegov-cloud/commit/9a8da1bca00091f7bf6d3838ab421afaaf85cd4f) - -##### Bugfix of deleting files - -Some files in the FileLinkExtension could not be deleted, they will return to the list if they are still linked in the text. Some files were invisibly linked in the text. This change will delete all invisible links on save and adds a command for deleting all current invisible links. - -`Bugfix` | [PRO-1248](https://linear.app/projuventute/issue/PRO-1248) | [e02233f3ca](https://github.com/onegov/onegov-cloud/commit/e02233f3cac2b3ed7d5c826642f426656fa08f14) - -##### Improve styling of alerts and errors. - -`Bugfix` | [OGC-1517](https://linear.app/onegovcloud/issue/OGC-1517) | [d91183ca7b](https://github.com/onegov/onegov-cloud/commit/d91183ca7bf796b57ff2aa3d0514953c217ded7f) - -##### Makes autofill of honeypot field in mTAN forms less likely - -`Bugfix` | [OGC-1484](https://linear.app/onegovcloud/issue/OGC-1484) | [6d6eb3ae16](https://github.com/onegov/onegov-cloud/commit/6d6eb3ae168533edf7004963a0661809e90d9068) - -### Tests - -##### Fixing failing test - -`Bugfix` | [OGC-1477](https://linear.app/onegovcloud/issue/OGC-1477) | [6956dc96b8](https://github.com/onegov/onegov-cloud/commit/6956dc96b87b7231cb46f45f5f9bf3d10b76d659) - -### Town6 - -##### Allow generic search results without a lead. - -`Feature` | [34f5a9580a](https://github.com/onegov/onegov-cloud/commit/34f5a9580a1452e4c8d340f5313c3160f2ae1ca4) - -##### Add RSS to news (#1236) - -`Feature` | [OGC-1512](https://linear.app/onegovcloud/issue/OGC-1512) | [fae58f3a9a](https://github.com/onegov/onegov-cloud/commit/fae58f3a9a6da931b6f4ed8f7cea1334b683a320) - -##### Remove newline between icon and text - -`Bugfix` | [OGC-1501](https://linear.app/onegovcloud/issue/OGC-1501) | [cd7e306b4b](https://github.com/onegov/onegov-cloud/commit/cd7e306b4be51587acdd8c289dba52b3ac12a263) - -##### Use closure to capture free variables - -`Bugfix` | [OGC-1255](https://linear.app/onegovcloud/issue/OGC-1255) | [088d5fc19f](https://github.com/onegov/onegov-cloud/commit/088d5fc19f479eea29beee1a0e9ce271dd42fe0e) - -## 2024.14 - -`2024-03-08` | [39058784ad...c181f4f875](https://github.com/OneGov/onegov-cloud/compare/39058784ad^...c181f4f875) - diff --git a/pyproject.toml b/pyproject.toml index 6774e878d5..9646436384 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,15 +35,12 @@ python_version = "3.11" follow_imports = "silent" namespace_packages = true explicit_package_bases = true -warn_unused_ignores = true -warn_redundant_casts = true -warn_unused_configs = true +strict = true +implicit_reexport = true warn_unreachable = true -disallow_any_generics = true -disallow_incomplete_defs = true -disallow_untyped_defs = true -strict_equality = true -extra_checks = true +warn_return_any = false +# FIXME: remove sqlalchemy when upgrading to SQlAlchemy 2.0 +untyped_calls_exclude = "sqlalchemy,pycurl,onegov.core.types" plugins = "sqlmypy" mypy_path = "$MYPY_CONFIG_FILE_DIR/src:$MYPY_CONFIG_FILE_DIR/stubs" @@ -72,13 +69,10 @@ exclude_dirs = [ skips = [ # ignore asserts "B101", - # ignore lxml.etree.fromstring (we may want to revisit this in the future) - "B320", # ignore meta-codes, we are aware of the implications "B403", "B404", "B405", - "B410", ] [tool.ruff] @@ -134,6 +128,7 @@ select = [ "E", "F", "FLY002", + "I002", "ISC", "N", "PERF", @@ -176,6 +171,7 @@ ignore = [ "RUF023", "RUF031", "RUF052", + "RUF056", # TODO: We would like to enable SIM102, but it has a ton of # violations, so it's a big job to clean it up "SIM102", @@ -189,7 +185,6 @@ ignore = [ "UP009", "UP012", "UP032", - "UP037", "UP038", ] unfixable = [] @@ -199,7 +194,7 @@ preview = true [tool.ruff.lint.extend-per-file-ignores] "src/onegov/core/types.py" = ["B018"] -"reportlab_settings.py" = ["N"] +"reportlab_settings.py" = ["N", "I002"] "*.pyi" = [ "E501", "N", @@ -220,6 +215,7 @@ preview = true "E306", "F841", "FLY002", + "I002", "ISC", "N", "Q", @@ -232,6 +228,9 @@ preview = true "UP", ] +[tool.ruff.lint.isort] +required-imports = ["from __future__ import annotations"] + [tool.ruff.lint.pep8-naming] extend-ignore-names = [ "afterFlowable", diff --git a/setup.cfg b/setup.cfg index c11478f7bd..503e204b53 100644 --- a/setup.cfg +++ b/setup.cfg @@ -179,6 +179,7 @@ dev = honyaku@git+https://github.com/seantis/honyaku#egg=honyaku lingua==3.12 pre-commit + pre-commit-uv pytest-profiling pytest-split pytest-testmon @@ -334,7 +335,7 @@ onegov_upgrades = onegov.winterthur = onegov.winterthur.upgrade [flake8] -select = TC0,TC2 +select = TC0,TC1 per_file_ignores = *.pyi: TC tests/**.py: TC diff --git a/src/onegov/activity/__init__.py b/src/onegov/activity/__init__.py index f1e4372abf..4b7a279297 100644 --- a/src/onegov/activity/__init__.py +++ b/src/onegov/activity/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.activity') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/activity/collections/__init__.py b/src/onegov/activity/collections/__init__.py index cac03ac656..38b726c785 100644 --- a/src/onegov/activity/collections/__init__.py +++ b/src/onegov/activity/collections/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.collections.activity import ActivityFilter from onegov.activity.collections.activity import ActivityCollection from onegov.activity.collections.attendee import AttendeeCollection diff --git a/src/onegov/activity/collections/activity.py b/src/onegov/activity/collections/activity.py index ba96701d3e..7974c14fe3 100644 --- a/src/onegov/activity/collections/activity.py +++ b/src/onegov/activity/collections/activity.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import secrets import sedate @@ -90,7 +92,7 @@ class ToggledArgs(TypedDict, total=False): ActivityT = TypeVar('ActivityT', bound=Activity) -AVAILABILITY_VALUES: set['AvailabilityType'] = {'none', 'few', 'many'} +AVAILABILITY_VALUES: set[AvailabilityType] = {'none', 'few', 'many'} class ActivityFilter: @@ -98,7 +100,7 @@ class ActivityFilter: # supported filters - should be named with a plural version that can # be turned into a singular with the removal of the last s # (i.e. slots => slot) - __slots__: tuple['FilterKey', ...] = ( + __slots__: tuple[FilterKey, ...] = ( 'age_ranges', 'available', 'price_ranges', @@ -119,20 +121,20 @@ class ActivityFilter: } age_ranges: set[tuple[int, int]] - available: set['AvailabilityType'] + available: set[AvailabilityType] price_ranges: set[tuple[int, int]] - dateranges: set[tuple['date', 'date']] + dateranges: set[tuple[date, date]] durations: set[int] municipalities: set[str] owners: set[str] period_ids: set[UUID] - states: set['ActivityState'] + states: set[ActivityState] tags: set[str] timelines: set[str] weekdays: set[int] volunteers: set[bool] - def __init__(self, **keywords: 'Unpack[FilterArgs]') -> None: + def __init__(self, **keywords: Unpack[FilterArgs]) -> None: for key in self.__slots__: if key in keywords: values = set(v) if (v := keywords[key]) else set() @@ -148,14 +150,14 @@ def __init__(self, **keywords: 'Unpack[FilterArgs]') -> None: setattr(self, key, set()) @property - def keywords(self) -> dict['FilterKey', str | list[str]]: + def keywords(self) -> dict[FilterKey, str | list[str]]: return { key: self.encode(key, value) for key in self.__slots__ if (value := getattr(self, key)) } - def toggled(self, **keywords: 'Unpack[ToggledArgs]') -> 'Self': + def toggled(self, **keywords: Unpack[ToggledArgs]) -> Self: # create a new filter with the toggled values toggled = copy(self) @@ -191,7 +193,7 @@ def adapt_age_ranges(self, values: set[str]) -> set[tuple[int, int]]: def adapt_price_ranges(self, values: set[str]) -> set[tuple[int, int]]: return self.adapt_num_ranges(values) - def adapt_dateranges(self, values: set[str]) -> set[tuple['date', 'date']]: + def adapt_dateranges(self, values: set[str]) -> set[tuple[date, date]]: return {v for v in map(date_range_decode, values) if v} def adapt_weekdays(self, values: set[str]) -> set[int]: @@ -243,7 +245,7 @@ def encode(self, key: str, value: object) -> str | list[str]: def contains_num_range( self, value: tuple[int, int], - ranges: 'Iterable[tuple[int, int]]' + ranges: Iterable[tuple[int, int]] ) -> bool: for r in ranges: if overlaps(r, value): @@ -261,8 +263,8 @@ class ActivityCollection(RangedPagination[ActivityT]): @overload def __init__( - self: 'ActivityCollection[Activity]', - session: 'Session', + self: ActivityCollection[Activity], + session: Session, type: Literal['*', 'generic'] = '*', pages: tuple[int, int] | None = None, filter: ActivityFilter | None = None @@ -271,7 +273,7 @@ def __init__( @overload def __init__( self, - session: 'Session', + session: Session, type: str, pages: tuple[int, int] | None = None, filter: ActivityFilter | None = None @@ -279,7 +281,7 @@ def __init__( def __init__( self, - session: 'Session', + session: Session, type: str = '*', pages: tuple[int, int] | None = None, filter: ActivityFilter | None = None @@ -289,14 +291,14 @@ def __init__( self.pages = pages or (0, 0) self.filter = filter or ActivityFilter() - def subset(self) -> 'Query[ActivityT]': + def subset(self) -> Query[ActivityT]: return self.query() @property def page_range(self) -> tuple[int, int]: return self.pages - def by_page_range(self, page_range: tuple[int, int] | None) -> 'Self': + def by_page_range(self, page_range: tuple[int, int] | None) -> Self: return self.__class__( self.session, type=self.type, @@ -311,7 +313,7 @@ def model_class(self) -> type[ActivityT]: Activity # type:ignore[arg-type] ) - def query_base(self) -> 'Query[ActivityT]': + def query_base(self) -> Query[ActivityT]: """ Returns the query based used by :meth:`query`. Overriding this function is useful to apply a general filter to the query before any other filter is applied. @@ -322,7 +324,7 @@ def query_base(self) -> 'Query[ActivityT]': """ return self.session.query(self.model_class) - def query(self) -> 'Query[ActivityT]': + def query(self) -> Query[ActivityT]: query = self.query_base() model_class = self.model_class @@ -460,8 +462,8 @@ def query(self) -> 'Query[ActivityT]': def for_filter( self, - **keywords: 'Unpack[ToggledArgs]' - ) -> 'Self': + **keywords: Unpack[ToggledArgs] + ) -> Self: """ Returns a new collection instance. The given tag is excluded if already in the list, included if not @@ -486,10 +488,10 @@ def by_id(self, id: UUID) -> ActivityT | None: def by_name(self, name: str) -> ActivityT | None: return self.query().filter(Activity.name == name).first() - def by_user(self, user: 'User') -> 'Query[ActivityT]': + def by_user(self, user: User) -> Query[ActivityT]: return self.query().filter(Activity.username == user.username) - def by_username(self, username: str) -> 'Query[ActivityT]': + def by_username(self, username: str) -> Query[ActivityT]: return self.query().filter(Activity.username == username) @property @@ -546,7 +548,7 @@ def add( title: str, username: str, lead: str | None = None, - text: 'Markup | None' = None, + text: Markup | None = None, tags: set[str] | None = None, name: str | None = None ) -> ActivityT: @@ -579,8 +581,8 @@ def delete(self, activity: Activity) -> None: def available_weeks( self, - period: 'Period | PeriodMeta | None' - ) -> 'Iterator[tuple[date, date]]': + period: Period | PeriodMeta | None + ) -> Iterator[tuple[date, date]]: if not period: return diff --git a/src/onegov/activity/collections/attendee.py b/src/onegov/activity/collections/attendee.py index e787570223..3c78f0ea85 100644 --- a/src/onegov/activity/collections/attendee.py +++ b/src/onegov/activity/collections/attendee.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.models import Attendee from onegov.core.collection import GenericCollection @@ -15,17 +17,17 @@ class AttendeeCollection(GenericCollection[Attendee]): def model_class(self) -> type[Attendee]: return Attendee - def by_user(self, user: 'User') -> 'Query[Attendee]': + def by_user(self, user: User) -> Query[Attendee]: return self.query().filter(self.model_class.username == user.username) - def by_username(self, username: str) -> 'Query[Attendee]': + def by_username(self, username: str) -> Query[Attendee]: return self.query().filter(self.model_class.username == username) def add( # type:ignore[override] self, - user: 'User', + user: User, name: str, - birth_date: 'date', + birth_date: date, gender: str | None, notes: str | None = None, differing_address: bool = False, diff --git a/src/onegov/activity/collections/booking.py b/src/onegov/activity/collections/booking.py index e250fb0802..87b7525d21 100644 --- a/src/onegov/activity/collections/booking.py +++ b/src/onegov/activity/collections/booking.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.models import Booking, Period from onegov.core.collection import GenericCollection from onegov.activity.matching.utils import unblockable, booking_order @@ -25,15 +27,15 @@ class BookingCollection(GenericCollection[Booking]): def __init__( self, - session: 'Session', - period_id: 'UUID | None' = None, + session: Session, + period_id: UUID | None = None, username: str | None = None ) -> None: super().__init__(session) self.period_id = period_id self.username = username - def query(self) -> 'Query[Booking]': + def query(self) -> Query[Booking]: query = super().query() if self.username is not None: @@ -44,10 +46,10 @@ def query(self) -> 'Query[Booking]': return query.order_by(self.model_class.priority) - def for_period(self, period: Period) -> 'Self': + def for_period(self, period: Period) -> Self: return self.__class__(self.session, period.id, self.username) - def for_username(self, username: str) -> 'Self': + def for_username(self, username: str) -> Self: return self.__class__(self.session, self.period_id, username) @property @@ -56,9 +58,9 @@ def model_class(self) -> type[Booking]: def count( self, - usernames: 'Collection[str] | Literal["*"]' = '*', - periods: 'Collection[UUID] | Literal["*"]' = '*', - states: 'Collection[str] | Literal["*"]' = '*' + usernames: Collection[str] | Literal['*'] = '*', + periods: Collection[UUID] | Literal['*'] = '*', + states: Collection[str] | Literal['*'] = '*' ) -> int: """ Returns the number of bookings, optionally filtered by usernames, periods and states. @@ -83,7 +85,7 @@ def count( def booking_count( self, username: str, - states: 'Collection[str] | Literal["*"]' = '*' + states: Collection[str] | Literal['*'] = '*' ) -> int: """ Returns the number of bookings in the active period. """ @@ -97,20 +99,20 @@ def booking_count( states=states ) - def by_user(self, user: 'User') -> 'Query[Booking]': + def by_user(self, user: User) -> Query[Booking]: return self.query().filter(Booking.username == user.username) - def by_username(self, username: str) -> 'Query[Booking]': + def by_username(self, username: str) -> Query[Booking]: return self.query().filter(Booking.username == username) - def by_occasion(self, occasion: 'Occasion') -> 'Query[Booking]': + def by_occasion(self, occasion: Occasion) -> Query[Booking]: return self.query().filter(Booking.occasion_id == occasion.id) def add( # type:ignore[override] self, - user: 'User', - attendee: 'Attendee', - occasion: 'Occasion', + user: User, + attendee: Attendee, + occasion: Occasion, priority: int | None = None, group_code: str | None = None ) -> Booking: @@ -195,7 +197,7 @@ def accept_booking(self, booking: Booking) -> None: def cancel_booking( self, booking: Booking, - score_function: 'ScoreFunction' = booking_order, + score_function: ScoreFunction = booking_order, cascade: bool = False ) -> None: """ Cancels the given booking. diff --git a/src/onegov/activity/collections/invoice.py b/src/onegov/activity/collections/invoice.py index 1bd619c6d8..c1db279a53 100644 --- a/src/onegov/activity/collections/invoice.py +++ b/src/onegov/activity/collections/invoice.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from decimal import Decimal from functools import cached_property from onegov.activity.models import Invoice, InvoiceItem @@ -22,7 +24,7 @@ class InvoiceCollection(GenericCollection[Invoice]): def __init__( self, - session: 'Session', + session: Session, period_id: UUID | None = None, user_id: UUID | None = None, schema: str = 'feriennet-v1', @@ -42,7 +44,7 @@ def __init__( def schema(self) -> Schema: return KNOWN_SCHEMAS[self.schema_name](**self.schema_config) - def query(self, ignore_period_id: bool = False) -> 'Query[Invoice]': + def query(self, ignore_period_id: bool = False) -> Query[Invoice]: q = super().query() if self.user_id: @@ -53,18 +55,18 @@ def query(self, ignore_period_id: bool = False) -> 'Query[Invoice]': return q - def query_items(self) -> 'Query[InvoiceItem]': + def query_items(self) -> Query[InvoiceItem]: return self.session.query(InvoiceItem).filter( InvoiceItem.invoice_id.in_( self.query().with_entities(Invoice.id).subquery() ) ) - def for_user_id(self, user_id: UUID | None) -> 'Self': + def for_user_id(self, user_id: UUID | None) -> Self: return self.__class__(self.session, self.period_id, user_id, self.schema_name, self.schema_config) - def for_period_id(self, period_id: UUID | None) -> 'Self': + def for_period_id(self, period_id: UUID | None) -> Self: return self.__class__(self.session, period_id, self.user_id, self.schema_name, self.schema_config) @@ -72,7 +74,7 @@ def for_schema( self, schema: str, schema_config: dict[str, Any] | None = None - ) -> 'Self': + ) -> Self: return self.__class__(self.session, self.period_id, self.user_id, schema, schema_config) @@ -108,10 +110,10 @@ def username(self) -> str | None: def model_class(self) -> type[Invoice]: return Invoice - def _invoice_ids(self) -> 'Query[tuple[UUID]]': + def _invoice_ids(self) -> Query[tuple[UUID]]: return self.query().with_entities(Invoice.id).subquery() - def _sum(self, condition: 'ColumnElement[bool]') -> Decimal: + def _sum(self, condition: ColumnElement[bool]) -> Decimal: q = self.session.query(func.sum(InvoiceItem.amount).label('amount')) q = q.filter(condition) @@ -137,7 +139,7 @@ def paid_amount(self) -> Decimal: def unpaid_count( self, - excluded_period_ids: 'Collection[UUID] | None' = None + excluded_period_ids: Collection[UUID] | None = None ) -> int: q = self.query().with_entities(func.count(Invoice.id)) diff --git a/src/onegov/activity/collections/occasion.py b/src/onegov/activity/collections/occasion.py index 09f5ead2d5..7b5ac6cc4e 100644 --- a/src/onegov/activity/collections/occasion.py +++ b/src/onegov/activity/collections/occasion.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from decimal import Decimal from onegov.activity.models import Occasion, OccasionDate from onegov.activity.types import BoundedIntegerRange @@ -30,14 +32,14 @@ def to_half_open_interval(lower: int, upper: int) -> BoundedIntegerRange: def add( # type:ignore[override] self, - activity: 'Activity', - period: 'Period', - start: 'datetime', - end: 'datetime', + activity: Activity, + period: Period, + start: datetime, + end: datetime, timezone: str, meeting_point: str | None = None, - age: 'Sequence[int] | None' = None, - spots: 'Sequence[int] | None' = None, + age: Sequence[int] | None = None, + spots: Sequence[int] | None = None, note: str | None = None, cost: Decimal = Decimal(0), exclude_from_overlap_check: bool = False @@ -61,8 +63,8 @@ def add( # type:ignore[override] def add_date( self, occasion: Occasion, - start: 'datetime', - end: 'datetime', + start: datetime, + end: datetime, timezone: str ) -> OccasionDate: @@ -83,8 +85,8 @@ def add_date( def find_date( self, occasion: Occasion, - start: 'datetime', - end: 'datetime', + start: datetime, + end: datetime, timezone: str ) -> OccasionDate | None: diff --git a/src/onegov/activity/collections/period.py b/src/onegov/activity/collections/period.py index 2951b0c93a..12e0e8d559 100644 --- a/src/onegov/activity/collections/period.py +++ b/src/onegov/activity/collections/period.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.models import Period from onegov.core.collection import GenericCollection @@ -16,13 +18,13 @@ def model_class(self) -> type[Period]: def add( # type:ignore[override] self, title: str, - prebooking: tuple['date | None', 'date | None'], - booking: tuple['date', 'date'], - execution: tuple['date', 'date'], + prebooking: tuple[date | None, date | None], + booking: tuple[date, date], + execution: tuple[date, date], active: bool = False, minutes_between: int | None = 0, deadline_days: int | None = None, - cancellation_date: 'date | None' = None, + cancellation_date: date | None = None, cancellation_days: int | None = None, finalizable: bool = True, confirmable: bool = True diff --git a/src/onegov/activity/collections/publication_request.py b/src/onegov/activity/collections/publication_request.py index c405f615bb..28c5c2bb06 100644 --- a/src/onegov/activity/collections/publication_request.py +++ b/src/onegov/activity/collections/publication_request.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.models.publication_request import PublicationRequest from onegov.core.collection import GenericCollection diff --git a/src/onegov/activity/collections/volunteer.py b/src/onegov/activity/collections/volunteer.py index 6f4662c331..cf14eb89ec 100644 --- a/src/onegov/activity/collections/volunteer.py +++ b/src/onegov/activity/collections/volunteer.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.models import Volunteer from onegov.core.collection import GenericCollection from onegov.core.orm.sql import as_selectable_from_path @@ -75,8 +77,8 @@ class VolunteerCollection(GenericCollection[Volunteer]): def __init__( self, - session: 'Session', - period: 'Period | PeriodMeta | None' + session: Session, + period: Period | PeriodMeta | None ) -> None: super().__init__(session) self.period = period @@ -86,10 +88,10 @@ def model_class(self) -> type[Volunteer]: return Volunteer @property - def period_id(self) -> 'UUID | None': + def period_id(self) -> UUID | None: return self.period and self.period.id or None - def report(self) -> 'Query[ReportRow]': + def report(self) -> Query[ReportRow]: stmt = as_selectable_from_path( module_path('onegov.activity', 'queries/volunteer-report.sql')) @@ -97,5 +99,5 @@ def report(self) -> 'Query[ReportRow]': return self.session.execute(query) - def for_period(self, period: 'Period | PeriodMeta | None') -> 'Self': + def for_period(self, period: Period | PeriodMeta | None) -> Self: return self.__class__(self.session, period) diff --git a/src/onegov/activity/errors.py b/src/onegov/activity/errors.py index efc17b0a3f..f019da0b8d 100644 --- a/src/onegov/activity/errors.py +++ b/src/onegov/activity/errors.py @@ -1,3 +1,6 @@ +from __future__ import annotations + + class BookingLimitReached(RuntimeError): def __init__(self) -> None: super().__init__('The booking limit has been reached') diff --git a/src/onegov/activity/iso20022.py b/src/onegov/activity/iso20022.py index 4d1293ebe7..70e5d4119c 100644 --- a/src/onegov/activity/iso20022.py +++ b/src/onegov/activity/iso20022.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re import stdnum.ch.esr as esr # type: ignore[import-untyped] @@ -57,7 +59,7 @@ def references(self) -> set[str]: # if possible, don't rely on manual extraction of the reference number. return {self.reference} - def extract_references(self) -> 'Iterator[str]': + def extract_references(self) -> Iterator[str]: if self.reference: yield self.reference @@ -113,7 +115,7 @@ def state(self) -> str: return 'unknown' -def transaction_entries(root: 'etree._Element') -> 'Iterator[etree._Element]': +def transaction_entries(root: etree._Element) -> Iterator[etree._Element]: """ Yields the transaction entries from the given Camt.053 or Camt.054 xml. This works because for our purposes the entries of those two formats are identical. @@ -180,14 +182,14 @@ def format_esr(esr_ref: str) -> str: def extract_transactions( xml: str, invoice_schema: str -) -> 'Iterator[Transaction]': +) -> Iterator[Transaction]: root = etree.fromstring(normalize_xml(xml).encode('utf-8')) - def first(element: 'etree._Element', xpath: str) -> Any | None: + def first(element: etree._Element, xpath: str) -> Any | None: elements = element.xpath(xpath) return elements[0] if elements else None - def joined(element: 'etree._Element', xpath: str) -> str: + def joined(element: etree._Element, xpath: str) -> str: return '\n'.join(element.xpath(xpath)) def as_decimal(text: str | None) -> Decimal | None: @@ -242,11 +244,11 @@ def as_date(text: str | None) -> date | None: def match_iso_20022_to_usernames( xml: str, - session: 'Session', - period_id: 'UUID', + session: Session, + period_id: UUID, schema: str, currency: str = 'CHF' -) -> 'Iterator[Transaction]': +) -> Iterator[Transaction]: """ Takes an ISO20022 camt.053 file and matches it with the invoice items in the database. @@ -259,7 +261,7 @@ def match_iso_20022_to_usernames( """ - def items(period_id: 'UUID | None' = None) -> 'Query[InvoiceItem]': + def items(period_id: UUID | None = None) -> Query[InvoiceItem]: invoices = InvoiceCollection(session, period_id=period_id) return invoices.query_items().outerjoin(Invoice).outerjoin(User) diff --git a/src/onegov/activity/matching/__init__.py b/src/onegov/activity/matching/__init__.py index f27cdfd86d..b4cb9bb7b2 100644 --- a/src/onegov/activity/matching/__init__.py +++ b/src/onegov/activity/matching/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.matching.core import deferred_acceptance from onegov.activity.matching.core import deferred_acceptance_from_database from onegov.activity.matching.interfaces import MatchableBooking diff --git a/src/onegov/activity/matching/core.py b/src/onegov/activity/matching/core.py index 709bb22da9..8a13ad5b45 100644 --- a/src/onegov/activity/matching/core.py +++ b/src/onegov/activity/matching/core.py @@ -4,6 +4,7 @@ quadratic runtime. """ +from __future__ import annotations from onegov.activity import Attendee, Booking, Occasion, Period from onegov.activity.matching.score import Scoring @@ -46,8 +47,8 @@ class AttendeeAgent(HashableID): def __init__( self, - id: 'UUID', - bookings: 'Iterable[Booking]', + id: UUID, + bookings: Iterable[Booking], limit: int | None = None, minutes_between: float = 0, alignment: Literal['day', 'week', 'month'] | None = None @@ -124,12 +125,12 @@ class OccasionAgent(HashableID): bookings: set[Booking] attendees: dict[Booking, AttendeeAgent] - score_function: 'ScoreFunction' + score_function: ScoreFunction def __init__( self, occasion: Occasion, - score_function: 'ScoreFunction | None' = None + score_function: ScoreFunction | None = None ) -> None: self.id = occasion.id @@ -190,14 +191,14 @@ def match(self, attendee: AttendeeAgent, booking: Booking) -> bool: def deferred_acceptance( - bookings: 'Sequence[Booking]', - occasions: 'Iterable[Occasion]', - score_function: 'ScoreFunction | None' = None, + bookings: Sequence[Booking], + occasions: Iterable[Occasion], + score_function: ScoreFunction | None = None, validity_check: bool = True, stability_check: bool = False, hard_budget: bool = True, default_limit: int | None = None, - attendee_limits: dict['UUID', int] | None = None, + attendee_limits: dict[UUID, int] | None = None, minutes_between: float = 0, alignment: Literal['day'] | None = None, sort_bookings: bool = True @@ -336,10 +337,10 @@ def deferred_acceptance( def deferred_acceptance_from_database( - session: 'Session', - period_id: 'UUID', + session: Session, + period_id: UUID, *, - score_function: 'ScoreFunction | None' = None, + score_function: ScoreFunction | None = None, validity_check: bool = True, stability_check: bool = False, hard_budget: bool = True, @@ -389,7 +390,7 @@ def deferred_acceptance_from_database( ) # write the changes to the database - def update_bookings(targets: set[Booking], state: 'BookingState') -> None: + def update_bookings(targets: set[Booking], state: BookingState) -> None: q = session.query(Booking) q = q.filter(Booking.state != state) q = q.filter(Booking.state != 'cancelled') @@ -406,8 +407,8 @@ def update_bookings(targets: set[Booking], state: 'BookingState') -> None: def is_stable( - attendees: 'Iterable[AttendeeAgent]', - occasions: 'Collection[OccasionAgent]' + attendees: Iterable[AttendeeAgent], + occasions: Collection[OccasionAgent] ) -> bool: """ Returns true if the matching between attendees and occasions is stable. diff --git a/src/onegov/activity/matching/interfaces.py b/src/onegov/activity/matching/interfaces.py index 26b02d784f..5c0a3fe32c 100644 --- a/src/onegov/activity/matching/interfaces.py +++ b/src/onegov/activity/matching/interfaces.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from abc import ABCMeta, abstractmethod @@ -19,7 +21,7 @@ class MatchableOccasion(metaclass=ABCMeta): @property @abstractmethod - def id(self) -> 'UUID': + def id(self) -> UUID: """ The id of the occasion. """ @property @@ -67,22 +69,22 @@ def __hash__(self) -> int: @property @abstractmethod - def id(self) -> 'UUID': + def id(self) -> UUID: """ The id of the booking. """ @property @abstractmethod - def occasion_id(self) -> 'UUID': + def occasion_id(self) -> UUID: """ Returns the id of the occasion this booking belongs to. """ @property @abstractmethod - def attendee_id(self) -> 'UUID': + def attendee_id(self) -> UUID: """ Returns the id of the attendee this booking belongs to. """ @property @abstractmethod - def state(self) -> 'BookingState': + def state(self) -> BookingState: """ Returns the state of the booking, one of: * "open" (for unassigned bookings) @@ -106,7 +108,7 @@ def priority(self) -> int: # FIXME: We probably also need to define an interface for OccasionDate @property @abstractmethod - def dates(self) -> 'Sequence[OccasionDate]': + def dates(self) -> Sequence[OccasionDate]: """ Returns the dates of the booking. """ @property diff --git a/src/onegov/activity/matching/score.py b/src/onegov/activity/matching/score.py index 8c8d3fcb53..ea176e4b42 100644 --- a/src/onegov/activity/matching/score.py +++ b/src/onegov/activity/matching/score.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import hashlib from decimal import Decimal @@ -21,11 +23,11 @@ class Scoring: """ - criteria: list['Callable[[Booking], float]'] + criteria: list[Callable[[Booking], float]] def __init__( self, - criteria: list['Callable[[Booking], float]'] | None = None + criteria: list[Callable[[Booking], float]] | None = None ) -> None: self.criteria = criteria or [PreferMotivated()] @@ -36,8 +38,8 @@ def __call__(self, booking: Booking) -> Decimal: def from_settings( cls, settings: dict[str, Any], - session: 'Session' - ) -> 'Self': + session: Session + ) -> Self: scoring = cls() @@ -83,7 +85,7 @@ class PreferMotivated: """ @classmethod - def from_session(cls, session: 'Session') -> 'Self': + def from_session(cls, session: Session) -> Self: return cls() def __call__(self, booking: Booking) -> int: @@ -101,14 +103,14 @@ class PreferInAgeBracket: def __init__( self, - get_age_range: 'Callable[[Booking], tuple[int, int]]', - get_attendee_age: 'Callable[[Booking], int]' + get_age_range: Callable[[Booking], tuple[int, int]], + get_attendee_age: Callable[[Booking], int] ): self.get_age_range = get_age_range self.get_attendee_age = get_attendee_age @classmethod - def from_session(cls, session: 'Session') -> 'Self': + def from_session(cls, session: Session) -> Self: attendees = None occasions = None @@ -160,11 +162,11 @@ class PreferOrganiserChildren: """ - def __init__(self, get_is_organiser_child: 'Callable[[Booking], bool]'): + def __init__(self, get_is_organiser_child: Callable[[Booking], bool]): self.get_is_organiser_child = get_is_organiser_child @classmethod - def from_session(cls, session: 'Session') -> 'Self': + def from_session(cls, session: Session) -> Self: organisers = None def get_is_organiser_child(booking: Booking) -> bool: @@ -192,11 +194,11 @@ def __call__(self, booking: Booking) -> float: class PreferAdminChildren: """ Scores bookings of children higher if their parents are admins. """ - def __init__(self, get_is_association_child: 'Callable[[Booking], bool]'): + def __init__(self, get_is_association_child: Callable[[Booking], bool]): self.get_is_association_child = get_is_association_child @classmethod - def from_session(cls, session: 'Session') -> 'Self': + def from_session(cls, session: Session) -> Self: members = None def get_is_association_child(booking: Booking) -> bool: @@ -237,11 +239,11 @@ class PreferGroups: """ - def __init__(self, get_group_score: 'Callable[[Booking], float]'): + def __init__(self, get_group_score: Callable[[Booking], float]): self.get_group_score = get_group_score @classmethod - def from_session(cls, session: 'Session') -> 'Self': + def from_session(cls, session: Session) -> Self: group_scores = None def unique_score_modifier(group_code: str) -> float: diff --git a/src/onegov/activity/matching/utils.py b/src/onegov/activity/matching/utils.py index 5885659f22..cbdc1671f0 100644 --- a/src/onegov/activity/matching/utils.py +++ b/src/onegov/activity/matching/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import log from onegov.activity.utils import dates_overlap from sortedcontainers import SortedSet @@ -21,8 +23,8 @@ def overlaps( - booking: 'Booking', - other: 'Booking | Occasion', + booking: Booking, + other: Booking | Occasion, minutes_between: float = 0, alignment: Literal['day', 'week', 'month'] | None = None, with_anti_affinity_check: bool = False @@ -97,7 +99,7 @@ def limit_reached(self, as_exception: bool = False) -> bool | None: class HashableID: - id: 'Hashable' + id: Hashable def __hash__(self) -> int: return hash(self.id) @@ -106,7 +108,7 @@ def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) and self.id == other.id -def booking_order(booking: 'Booking') -> tuple['Decimal', int, 'UUID']: +def booking_order(booking: Booking) -> tuple[Decimal, int, UUID]: """ Keeps the bookings predictably sorted from highest to lowest priority. """ @@ -115,14 +117,14 @@ def booking_order(booking: 'Booking') -> tuple['Decimal', int, 'UUID']: def unblockable( - accepted: 'Iterable[Booking]', - blocked: 'Iterable[Booking]', + accepted: Iterable[Booking], + blocked: Iterable[Booking], # NOTE: value defaults don't yet have an exception for type params # with a default type. So we need to ignore here, despite the # types matching. - key: 'Callable[[Booking], OrderT]' = booking_order, # type:ignore + key: Callable[[Booking], OrderT] = booking_order, # type:ignore with_anti_affinity_check: bool = False -) -> 'SortedKeySet[Booking, OrderT]': +) -> SortedKeySet[Booking, OrderT]: """ Returns a set of items in the blocked set which do not block with anything. The set is ordered using :func:`booking_order`. diff --git a/src/onegov/activity/models/__init__.py b/src/onegov/activity/models/__init__.py index b4533dc808..aede24afe5 100644 --- a/src/onegov/activity/models/__init__.py +++ b/src/onegov/activity/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.models.activity import Activity, ACTIVITY_STATES from onegov.activity.models.attendee import Attendee from onegov.activity.models.booking import Booking diff --git a/src/onegov/activity/models/activity.py b/src/onegov/activity/models/activity.py index 5b5f91264f..3dd3d937b8 100644 --- a/src/onegov/activity/models/activity.py +++ b/src/onegov/activity/models/activity.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.models.occasion import Occasion from onegov.activity.models.period import Period from onegov.activity.utils import extract_thumbnail, extract_municipality @@ -38,7 +40,7 @@ # Note, a database migration is needed if these states are changed -ACTIVITY_STATES: tuple['ActivityState', ...] = ( +ACTIVITY_STATES: tuple[ActivityState, ...] = ( 'preview', 'proposed', 'accepted', @@ -58,39 +60,39 @@ class Activity(Base, ContentMixin, TimestampMixin): __tablename__ = 'activities' #: An internal id for references (not public) - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: A nice id for the url, readable by humans - name: 'Column[str]' = Column(Text, nullable=False, unique=True) + name: Column[str] = Column(Text, nullable=False, unique=True) #: The title of the activity - title: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) #: The normalized title for sorting - order: 'Column[str]' = Column(Text, nullable=False, index=True) + order: Column[str] = Column(Text, nullable=False, index=True) #: Describes the activity briefly - lead: 'dict_property[str | None]' = meta_property() + lead: dict_property[str | None] = meta_property() #: Describes the activity in detail text = dict_markup_property('content') #: The thumbnail shown in the overview - thumbnail: 'dict_property[str | None]' = meta_property() + thumbnail: dict_property[str | None] = meta_property() #: Tags/Categories of the activity - _tags: 'Column[dict[str, str] | None]' = Column( # type:ignore - MutableDict.as_mutable(HSTORE), + _tags: Column[dict[str, str] | None] = Column( # type:ignore + MutableDict.as_mutable(HSTORE), # type:ignore[no-untyped-call] nullable=True, name='tags' ) #: The user to which this activity belongs to (organiser) - username: 'Column[str]' = Column( + username: Column[str] = Column( Text, ForeignKey(User.username), nullable=False @@ -98,19 +100,19 @@ class Activity(Base, ContentMixin, TimestampMixin): #: The user which initially reported this activity (same as username, but #: this value may not change after initialisation) - reporter: 'Column[str]' = Column(Text, nullable=False) + reporter: Column[str] = Column(Text, nullable=False) #: Describes the location of the activity - location: 'Column[str | None]' = Column(Text, nullable=True) + location: Column[str | None] = Column(Text, nullable=True) #: The municipality in which the activity is held, from the location - municipality: 'Column[str | None]' = Column(Text, nullable=True) + municipality: Column[str | None] = Column(Text, nullable=True) #: Access the user linked to this activity - user: 'relationship[User]' = relationship(User) + user: relationship[User] = relationship(User) #: The occasions linked to this activity - occasions: 'relationship[list[Occasion]]' = relationship( + occasions: relationship[list[Occasion]] = relationship( Occasion, order_by='Occasion.order', back_populates='activity' @@ -120,21 +122,21 @@ class Activity(Base, ContentMixin, TimestampMixin): #: subclasses of this class. See #: ``_. - type: 'Column[str]' = Column( + type: Column[str] = Column( Text, nullable=False, default=lambda: 'generic' ) #: the state of the activity - state: 'Column[ActivityState]' = Column( + state: Column[ActivityState] = Column( Enum(*ACTIVITY_STATES, name='activity_state'), # type:ignore[arg-type] nullable=False, default='preview' ) #: The publication requests linked to this activity - publication_requests: 'relationship[list[PublicationRequest]]' + publication_requests: relationship[list[PublicationRequest]] publication_requests = relationship( 'PublicationRequest', back_populates='activity' @@ -173,21 +175,21 @@ def tags(self) -> set[str]: # FIXME: asymmetric property @tags.setter - def tags(self, value: 'Iterable[str]') -> None: + def tags(self, value: Iterable[str]) -> None: self._tags = dict.fromkeys(value, '') if value else None - def propose(self) -> 'Self': + def propose(self) -> Self: assert self.state in ('preview', 'proposed') self.state = 'proposed' return self - def accept(self) -> 'Self': + def accept(self) -> Self: self.state = 'accepted' return self - def archive(self) -> 'Self': + def archive(self) -> Self: self.state = 'archived' return self @@ -196,11 +198,11 @@ def create_publication_request( self, period: Period, **kwargs: Any # TODO: better type safety - ) -> 'PublicationRequest': + ) -> PublicationRequest: return self.requests.add(activity=self, period=period, **kwargs) @property - def requests(self) -> 'PublicationRequestCollection': + def requests(self) -> PublicationRequestCollection: # XXX circular imports from onegov.activity.collections.publication_request import ( PublicationRequestCollection) @@ -208,7 +210,7 @@ def requests(self) -> 'PublicationRequestCollection': return PublicationRequestCollection(object_session(self)) @property - def latest_request(self) -> 'PublicationRequest | None': + def latest_request(self) -> PublicationRequest | None: q = self.requests.query() q = q.filter_by(activity_id=self.id) q = q.join(Period) @@ -218,8 +220,8 @@ def latest_request(self) -> 'PublicationRequest | None': def request_by_period( self, - period: 'Period | PeriodMeta | None' - ) -> 'PublicationRequest | None': + period: Period | PeriodMeta | None + ) -> PublicationRequest | None: if not period: return None @@ -228,7 +230,7 @@ def request_by_period( return q.first() - def has_occasion_in_period(self, period: 'Period | PeriodMeta') -> bool: + def has_occasion_in_period(self, period: Period | PeriodMeta) -> bool: q = object_session(self).query( exists().where(and_( Occasion.activity_id == self.id, diff --git a/src/onegov/activity/models/age_barrier.py b/src/onegov/activity/models/age_barrier.py index 94c366deb4..5105865403 100644 --- a/src/onegov/activity/models/age_barrier.py +++ b/src/onegov/activity/models/age_barrier.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date, datetime from dateutil import relativedelta @@ -6,7 +8,7 @@ class AgeBarrier: """ Holds various age barrier approaches available to the period. """ - registry: dict[str, type['AgeBarrier']] = {} + registry: dict[str, type[AgeBarrier]] = {} def __init_subclass__(cls, name: str, **kwargs: object): assert name not in cls.registry @@ -20,7 +22,7 @@ def from_name( name: str, *args: object, **kwargs: object - ) -> 'AgeBarrier': + ) -> AgeBarrier: return cls.registry[name](*args, **kwargs) def is_too_young( diff --git a/src/onegov/activity/models/attendee.py b/src/onegov/activity/models/attendee.py index 36bafcff07..eed2bb126e 100644 --- a/src/onegov/activity/models/attendee.py +++ b/src/onegov/activity/models/attendee.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from onegov.activity.models.booking import Booking from onegov.core.orm import Base @@ -75,55 +77,55 @@ def __hash__(self) -> int: return hash(self.id) #: the public id of the attendee - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the user owning the attendee - username: 'Column[str]' = Column( + username: Column[str] = Column( Text, ForeignKey('users.username'), nullable=False ) #: the name of the attendee (incl. first / lastname ) - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: birth date of the attendee for the age calculation - birth_date: 'Column[date]' = Column(Date, nullable=False) + birth_date: Column[date] = Column(Date, nullable=False) #: we use text for possible gender fluidity in the future ;) - gender: 'Column[str | None]' = Column(Text, nullable=True) + gender: Column[str | None] = Column(Text, nullable=True) #: notes about the attendee by the parents (e.g. allergies) - notes: 'Column[str | None]' = Column(Text, nullable=True) + notes: Column[str | None] = Column(Text, nullable=True) #: if the address of the attendee differs from the user address - differing_address: 'Column[bool]' = Column( + differing_address: Column[bool] = Column( Boolean, default=False, nullable=False ) #: address of the attendee (street and number) - address: 'Column[str | None]' = Column(Text, nullable=True) + address: Column[str | None] = Column(Text, nullable=True) #: zip code of the attendee - zip_code: 'Column[str | None]' = Column(Text, nullable=True) + zip_code: Column[str | None] = Column(Text, nullable=True) #: place of the attendee - place: 'Column[str | None]' = Column(Text, nullable=True) + place: Column[str | None] = Column(Text, nullable=True) #: political municipality, only if activated in settings - political_municipality: 'Column[str | None]' = Column(Text, nullable=True) + political_municipality: Column[str | None] = Column(Text, nullable=True) #: the maximum number of bookings the attendee wishes to get in each period - limit: 'Column[int | None]' = Column(Integer, nullable=True) + limit: Column[int | None] = Column(Integer, nullable=True) #: access the user linked to this booking - user: 'relationship[User]' = relationship('User') + user: relationship[User] = relationship('User') #: a secondary id used for subscriptions only - subscriptions are ical urls #: with public permission, by using a separate id we mitigate the risk of @@ -132,7 +134,7 @@ def __hash__(self) -> int: #: #: furthermore, subscription ids can be changed in the future to invalidate #: all existing subscription urls for one or all attendees. - subscription_token: 'Column[str]' = Column( + subscription_token: Column[str] = Column( Text, nullable=False, unique=True, @@ -158,11 +160,11 @@ def age(self) -> int: return today.year - birth.year - extra @age.expression # type:ignore[no-redef] - def age(cls) -> 'ColumnElement[int]': + def age(cls) -> ColumnElement[int]: return func.extract('year', func.age(cls.birth_date)) @hybrid_method # type:ignore[no-redef] - def happiness(self, period_id: 'uuid.UUID') -> float | None: + def happiness(self, period_id: uuid.UUID) -> float | None: """ Returns the happiness of the attende in the given period. The happiness is a value between 0.0 and 1.0, indicating how many @@ -200,8 +202,8 @@ def happiness(self, period_id: 'uuid.UUID') -> float | None: @happiness.expression # type:ignore[no-redef] def happiness( cls, - period_id: 'uuid.UUID' - ) -> 'ColumnElement[float | None]': + period_id: uuid.UUID + ) -> ColumnElement[float | None]: return select([ # force the result to be a float instead of a decimal type_coerce( @@ -221,7 +223,7 @@ def happiness( )).label('happiness') #: The bookings linked to this attendee - bookings: 'relationship[list[Booking]]' = relationship( + bookings: relationship[list[Booking]] = relationship( 'Booking', order_by='Booking.created', back_populates='attendee' diff --git a/src/onegov/activity/models/booking.py b/src/onegov/activity/models/booking.py index 2136bf3d36..a552a7cd89 100644 --- a/src/onegov/activity/models/booking.py +++ b/src/onegov/activity/models/booking.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.models.occasion import Occasion from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin @@ -63,47 +65,47 @@ def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) and self.id == other.id #: the public id of the booking - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the user owning the booking - username: 'Column[str]' = Column( + username: Column[str] = Column( Text, ForeignKey('users.username'), nullable=False ) #: the priority of the booking, a higher number = a higher priority - priority: 'Column[int]' = Column(Integer, nullable=False, default=0) + priority: Column[int] = Column(Integer, nullable=False, default=0) #: the group code of the booking, if missing the booking is not in a group - group_code: 'Column[str | None]' = Column(Text, nullable=True) + group_code: Column[str | None] = Column(Text, nullable=True) #: the attendee behind this booking - attendee_id: 'Column[uuid.UUID]' = Column( + attendee_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('attendees.id'), nullable=False ) #: the occasion this booking belongs to - occasion_id: 'Column[uuid.UUID]' = Column( + occasion_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('occasions.id'), nullable=False ) #: the cost of the booking - cost: 'Column[Decimal | None]' = Column( + cost: Column[Decimal | None] = Column( Numeric(precision=8, scale=2), nullable=True ) #: the calculated score of the booking - score: 'Column[Decimal]' = Column( + score: Column[Decimal] = Column( Numeric(precision=14, scale=9), nullable=False, default=0 @@ -111,17 +113,17 @@ def __eq__(self, other: object) -> bool: if TYPE_CHECKING: # FIXME: We should be able to get rid of this workaround in the future - period_id: 'Column[uuid.UUID]' + period_id: Column[uuid.UUID] #: the period this booking belongs to @aggregated('occasion', Column( # type:ignore[no-redef] UUID, ForeignKey('periods.id'), nullable=False) ) - def period_id(self) -> 'ColumnElement[uuid.UUID]': + def period_id(self) -> ColumnElement[uuid.UUID]: return func.coalesce(Occasion.period_id, None) #: the state of the booking - state: 'Column[BookingState]' = Column( + state: Column[BookingState] = Column( Enum( # type:ignore[arg-type] 'open', 'blocked', @@ -143,29 +145,29 @@ def period_id(self) -> 'ColumnElement[uuid.UUID]': ) #: access the user linked to this booking - user: 'relationship[User]' = relationship('User') + user: relationship[User] = relationship('User') #: access the attendee linked to this booking - attendee: 'relationship[Attendee]' = relationship( + attendee: relationship[Attendee] = relationship( 'Attendee', back_populates='bookings' ) #: access the occasion linked to this booking - occasion: 'relationship[Occasion]' = relationship( + occasion: relationship[Occasion] = relationship( Occasion, back_populates='bookings' ) #: access the period linked to this booking - period: 'relationship[Period]' = relationship( + period: relationship[Period] = relationship( 'Period', back_populates='bookings' ) def group_code_count( self, - states: 'BookingStates | Literal["*"]' = ('open', 'accepted') + states: BookingStates | Literal['*'] = ('open', 'accepted') ) -> int: """ Returns the number of bookings with the same group code. """ query = object_session(self).query(Booking).with_entities( @@ -177,7 +179,7 @@ def group_code_count( return query.scalar() - def period_bound_booking_state(self, period: 'Period') -> 'BookingState': + def period_bound_booking_state(self, period: Period) -> BookingState: """ During pre-booking we don't show the actual state of the booking, unless the occasion was cancelled, otherwise the user might see accepted bookings at a point where those states are not confirmed yet. @@ -261,7 +263,7 @@ def starred(self) -> bool: return self.priority & 1 << 0 != 0 @starred.expression # type:ignore[no-redef] - def starred(cls) -> 'ColumnElement[bool]': + def starred(cls) -> ColumnElement[bool]: return cls.priority.op('&')(1 << 0) != 0 @hybrid_property # type:ignore[no-redef] @@ -269,11 +271,11 @@ def nobbled(self) -> bool: return self.priority & 1 << 1 != 0 @nobbled.expression # type:ignore[no-redef] - def nobbled(cls) -> 'ColumnElement[bool]': + def nobbled(cls) -> ColumnElement[bool]: return cls.priority.op('&')(1 << 1) != 0 @property - def dates(self) -> list['OccasionDate']: + def dates(self) -> list[OccasionDate]: return self.occasion.dates @property @@ -282,7 +284,7 @@ def order(self) -> int | None: def overlaps( self, - other: 'Booking', + other: Booking, with_anti_affinity_check: bool = False ) -> bool: # XXX circular import diff --git a/src/onegov/activity/models/invoice.py b/src/onegov/activity/models/invoice.py index 8609184c41..159d14e66b 100644 --- a/src/onegov/activity/models/invoice.py +++ b/src/onegov/activity/models/invoice.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.models.invoice_item import InvoiceItem, SCALE from onegov.activity.models.period import Period from onegov.core.orm import Base @@ -25,7 +27,7 @@ def sync_invoice_items( - items: 'Iterable[InvoiceItem]', + items: Iterable[InvoiceItem], capture: bool = True ) -> None: @@ -54,41 +56,41 @@ class Invoice(Base, TimestampMixin): __tablename__ = 'invoices' #: the public id of the invoice - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the period to which this invoice belongs to - period_id: 'Column[uuid.UUID]' = Column( + period_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('periods.id'), nullable=False ) - period: 'relationship[Period]' = relationship( + period: relationship[Period] = relationship( Period, back_populates='invoices' ) #: the user to which the invoice belongs - user_id: 'Column[uuid.UUID]' = Column( + user_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('users.id'), nullable=False ) # FIXME: Do we need this backref? It's across module boundaries, so # not the best for proper module isolation - user: 'relationship[User]' = relationship(User, backref='invoices') + user: relationship[User] = relationship(User, backref='invoices') #: the specific items linked with this invoice - items: 'relationship[list[InvoiceItem]]' = relationship( + items: relationship[list[InvoiceItem]] = relationship( InvoiceItem, back_populates='invoice' ) #: the references pointing to this invoice - references: 'relationship[list[InvoiceReference]]' = relationship( + references: relationship[list[InvoiceReference]] = relationship( 'InvoiceReference', back_populates='invoice', cascade='all, delete-orphan' @@ -124,10 +126,10 @@ def add( self, group: str, text: str, - unit: 'Decimal', - quantity: 'Decimal', + unit: Decimal, + quantity: Decimal, organizer: str = '', - attendee_id: 'uuid.UUID | None' = None, + attendee_id: uuid.UUID | None = None, flush: bool = True, **kwargs: Any # FIXME: type safety for optional arguments ) -> InvoiceItem: @@ -164,7 +166,7 @@ def has_online_payments(self) -> bool: def discourage_changes_for_items( self, - items: 'Iterable[InvoiceItem]' + items: Iterable[InvoiceItem] ) -> bool: for item in items: if item.source == 'xml': @@ -174,7 +176,7 @@ def discourage_changes_for_items( def disable_changes_for_items( self, - items: 'Iterable[InvoiceItem]' + items: Iterable[InvoiceItem] ) -> bool: for item in items: if not item.source: @@ -191,7 +193,7 @@ def disable_changes_for_items( def has_online_payments_for_items( self, - items: 'Iterable[InvoiceItem]' + items: Iterable[InvoiceItem] ) -> bool: for item in items: if not item.source or item.source == 'xml': @@ -213,11 +215,11 @@ def paid(self) -> bool: # paid + unpaid @hybrid_property # type:ignore[no-redef] - def total_amount(self) -> 'Decimal': + def total_amount(self) -> Decimal: return self.outstanding_amount + self.paid_amount @total_amount.expression # type:ignore[no-redef] - def total_amount(cls) -> 'ColumnElement[Decimal]': + def total_amount(cls) -> ColumnElement[Decimal]: return select([func.sum(InvoiceItem.amount)]).where( InvoiceItem.invoice_id == cls.id ).label('total_amount') @@ -241,14 +243,14 @@ def outstanding_amount(cls): # unpaid only @hybrid_property # type:ignore[no-redef] - def paid_amount(self) -> 'Decimal': + def paid_amount(self) -> Decimal: return round( sum(item.amount for item in self.items if item.paid), SCALE ) @paid_amount.expression # type:ignore[no-redef] - def paid_amount(cls) -> 'ColumnElement[Decimal]': + def paid_amount(cls) -> ColumnElement[Decimal]: return select([func.sum(InvoiceItem.amount)]).where( and_( InvoiceItem.invoice_id == cls.id, diff --git a/src/onegov/activity/models/invoice_item.py b/src/onegov/activity/models/invoice_item.py index d11515d552..8273f8a653 100644 --- a/src/onegov/activity/models/invoice_item.py +++ b/src/onegov/activity/models/invoice_item.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -36,7 +38,7 @@ class InvoiceItem(Base, TimestampMixin, PayableManyTimes): __tablename__ = 'invoice_items' #: the public id of the invoice item - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 @@ -44,56 +46,56 @@ class InvoiceItem(Base, TimestampMixin, PayableManyTimes): #: the invoice this item belongs to # FIXME: Shouldn't this be nullable=False? - invoice_id: 'Column[uuid.UUID | None]' = Column( + invoice_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey('invoices.id') ) - invoice: 'relationship[Invoice]' = relationship( + invoice: relationship[Invoice] = relationship( 'Invoice', back_populates='items' ) #: the attendee, if the item is connected to an attendee - attendee_id: 'Column[uuid.UUID | None]' = Column( + attendee_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey('attendees.id'), nullable=True ) #: the item group (all items with the same text are visually grouped) - group: 'Column[str]' = Column(Text, nullable=False) + group: Column[str] = Column(Text, nullable=False) #: a secondary group who is not necessarily grouped visually - family: 'Column[str | None]' = Column(Text, nullable=True) + family: Column[str | None] = Column(Text, nullable=True) #: the item text - text: 'Column[str]' = Column(Text, nullable=False) + text: Column[str] = Column(Text, nullable=False) #: organizer (if the item is an activity) - organizer: 'Column[str | None]' = Column(Text, nullable=True) + organizer: Column[str | None] = Column(Text, nullable=True) #: true if paid - paid: 'Column[bool]' = Column(Boolean, nullable=False, default=False) + paid: Column[bool] = Column(Boolean, nullable=False, default=False) #: the payment date - payment_date: 'Column[date | None]' = Column(Date, nullable=True) + payment_date: Column[date | None] = Column(Date, nullable=True) #: the transaction id if paid through a bank or online transaction - tid: 'Column[str | None]' = Column(Text, nullable=True) + tid: Column[str | None] = Column(Text, nullable=True) #: the source of the transaction id, e.g. stripe, xml - source: 'Column[str | None]' = Column(Text, nullable=True) + source: Column[str | None] = Column(Text, nullable=True) #: the unit to pay.. # FIXME: I don't think this should be nullable - unit: 'Column[Decimal | None]' = Column( + unit: Column[Decimal | None] = Column( Numeric(precision=PRECISION, scale=SCALE), nullable=True ) #: ..multiplied by the quantity.. # FIXME: and neither should this be - quantity: 'Column[Decimal | None]' = Column( + quantity: Column[Decimal | None] = Column( Numeric(precision=PRECISION, scale=SCALE), nullable=True ) @@ -103,13 +105,13 @@ class InvoiceItem(Base, TimestampMixin, PayableManyTimes): #: ..together form the amount @hybrid_property # type: ignore[no-redef] - def amount(self) -> 'Decimal | None': + def amount(self) -> Decimal | None: if self.unit is None or self.quantity is None: return None return round(self.unit, SCALE) * round(self.quantity, SCALE) @amount.expression # type:ignore[no-redef] - def amount(cls) -> 'ColumnElement[Decimal | None]': + def amount(cls) -> ColumnElement[Decimal | None]: return cls.unit * cls.quantity @validates('source') diff --git a/src/onegov/activity/models/invoice_reference.py b/src/onegov/activity/models/invoice_reference.py index e87016bf7e..6e6f2e72ae 100644 --- a/src/onegov/activity/models/invoice_reference.py +++ b/src/onegov/activity/models/invoice_reference.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re import secrets import string @@ -20,7 +22,7 @@ from .invoice import Invoice -KNOWN_SCHEMAS: dict[str, type['Schema']] = {} +KNOWN_SCHEMAS: dict[str, type[Schema]] = {} INVALID_REFERENCE_CHARS_EX = re.compile(r'[^Q0-9A-F]+') REFERENCE_EX = re.compile(r'Q{1}[A-F0-9]{10}') @@ -57,25 +59,25 @@ class InvoiceReference(Base, TimestampMixin): __tablename__ = 'invoice_references' #: the unique reference - reference: 'Column[str]' = Column(Text, primary_key=True) + reference: Column[str] = Column(Text, primary_key=True) #: the referenced invoice - invoice_id: 'Column[uuid.UUID]' = Column( + invoice_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('invoices.id'), nullable=False ) - invoice: 'relationship[Invoice]' = relationship( + invoice: relationship[Invoice] = relationship( 'Invoice', back_populates='references' ) #: the schema used to generate the invoice - schema: 'Column[str]' = Column(Text, nullable=False) + schema: Column[str] = Column(Text, nullable=False) #: groups schema name and its config to identify records created by a #: given schema and config - bucket: 'Column[str]' = Column(Text, nullable=False) + bucket: Column[str] = Column(Text, nullable=False) __table_args__ = ( UniqueConstraint( @@ -149,8 +151,8 @@ def render_bucket( def link( self, - session: 'Session', - invoice: 'Invoice', + session: Session, + invoice: Invoice, optimistic: bool = False, flush: bool = True ) -> InvoiceReference | None: diff --git a/src/onegov/activity/models/occasion.py b/src/onegov/activity/models/occasion.py index 462a68a62b..601fa66a49 100644 --- a/src/onegov/activity/models/occasion.py +++ b/src/onegov/activity/models/occasion.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate from datetime import date, datetime, timedelta @@ -49,36 +51,36 @@ def __hash__(self) -> int: return hash(self.id) #: the public id of this occasion - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: Describes the meeting point of the occasion - meeting_point: 'Column[str | None]' = Column(Text, nullable=True) + meeting_point: Column[str | None] = Column(Text, nullable=True) #: The expected age of participants - age: 'Column[BoundedIntegerRange]' = Column( + age: Column[BoundedIntegerRange] = Column( INT4RANGE, nullable=False, default=BoundedIntegerRange(6, 17, bounds='[]') ) #: The expected number of participants - spots: 'Column[BoundedIntegerRange]' = Column( + spots: Column[BoundedIntegerRange] = Column( INT4RANGE, nullable=False, default=BoundedIntegerRange(0, 10, bounds='[]') ) #: A note about the occurrence - note: 'Column[str | None]' = Column(Text, nullable=True) + note: Column[str | None] = Column(Text, nullable=True) #: The cost of the occasion (max value is 100'000.00), the currency is #: assumed to be CHF as this system will probably never be used outside #: Switzerland - cost: 'Column[Decimal | None]' = Column( + cost: Column[Decimal | None] = Column( Numeric(precision=8, scale=2), nullable=True ) @@ -88,23 +90,23 @@ def __hash__(self) -> int: #: means that the period's booking cost is taken. #: #: In all-inclusive periods, this value is ignored. - booking_cost: 'Column[Decimal | None]' = Column( + booking_cost: Column[Decimal | None] = Column( Numeric(precision=8, scale=2), nullable=True ) #: The activity this occasion belongs to - activity_id: 'Column[uuid.UUID]' = Column( + activity_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('activities.id', use_alter=True), nullable=False ) - activity: 'relationship[Activity]' = relationship( + activity: relationship[Activity] = relationship( 'Activity', back_populates='occasions' ) - accepted: 'relationship[Sequence[Booking]]' = relationship( + accepted: relationship[Sequence[Booking]] = relationship( 'Booking', primaryjoin=("""and_( Booking.occasion_id == Occasion.id, @@ -114,29 +116,29 @@ def __hash__(self) -> int: ) #: The period this occasion belongs to - period_id: 'Column[uuid.UUID]' = Column( + period_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('periods.id', use_alter=True), nullable=False ) - period: 'relationship[Period]' = relationship( + period: relationship[Period] = relationship( 'Period', back_populates='occasions' ) #: True if the occasion has been cancelled - cancelled: 'Column[bool]' = Column(Boolean, nullable=False, default=False) + cancelled: Column[bool] = Column(Boolean, nullable=False, default=False) #: The duration defined by the associated dates # FIXME: should these be nullable=False? - duration: 'Column[int | None]' = Column(Integer, default=0) + duration: Column[int | None] = Column(Integer, default=0) #: The default order # FIXME: should these be nullable=False? - order: 'Column[int | None]' = Column(Integer, default=0) + order: Column[int | None] = Column(Integer, default=0) #: Pretend like this occasion doesn't use any time - exclude_from_overlap_check: 'Column[bool]' = Column( + exclude_from_overlap_check: Column[bool] = Column( Boolean, nullable=False, default=False @@ -144,7 +146,7 @@ def __hash__(self) -> int: #: This occasion can be booked, even if the booking limit has been reached #: (does not currently apply to the matching, only to confirmed periods) - exempt_from_booking_limit: 'Column[bool]' = Column( + exempt_from_booking_limit: Column[bool] = Column( Boolean, nullable=False, default=False @@ -152,39 +154,39 @@ def __hash__(self) -> int: #: Days of the year on which this occasion is active (1 - 365) #: January 1st - 2nd would be [1, 2], February 1st would be [32] - active_days: 'Column[list[int]]' = Column( + active_days: Column[list[int]] = Column( ARRAY(Integer), nullable=False, default=list ) #: Weekdays on which this occasion is active - weekdays: 'Column[list[int]]' = Column( + weekdays: Column[list[int]] = Column( ARRAY(Integer), nullable=False, default=list ) #: Indicates if an occasion needs volunteers or not - seeking_volunteers: 'Column[bool]' = Column( + seeking_volunteers: Column[bool] = Column( Boolean, nullable=False, default=False ) @aggregated('accepted', Column(Integer, default=0)) - def attendee_count(self) -> 'ColumnElement[int]': + def attendee_count(self) -> ColumnElement[int]: return func.count('1') #: The bookings linked to this occasion - bookings: 'relationship[list[Booking]]' = relationship( + bookings: relationship[list[Booking]] = relationship( 'Booking', order_by='Booking.created', back_populates='occasion' ) #: The dates associated with this occasion (loaded eagerly) - dates: 'relationship[list[OccasionDate]]' = relationship( + dates: relationship[list[OccasionDate]] = relationship( 'OccasionDate', cascade='all,delete', order_by='OccasionDate.start', @@ -193,7 +195,7 @@ def attendee_count(self) -> 'ColumnElement[int]': ) #: The needs associated with this occasion - needs: 'relationship[list[OccasionNeed]]' = relationship( + needs: relationship[list[OccasionNeed]] = relationship( 'OccasionNeed', cascade='all,delete', order_by='OccasionNeed.name', @@ -248,7 +250,7 @@ def total_cost(self) -> Decimal: return base @total_cost.expression # type:ignore[no-redef] - def total_cost(cls) -> 'ColumnElement[Decimal]': + def total_cost(cls) -> ColumnElement[Decimal]: from onegov.activity.models.period import Period return coalesce(Occasion.cost, 0) + case([ @@ -260,7 +262,7 @@ def total_cost(cls) -> 'ColumnElement[Decimal]': def compute_duration( self, - dates: 'Collection[OccasionDate] | None' + dates: Collection[OccasionDate] | None ) -> int: if not dates: @@ -278,7 +280,7 @@ def compute_duration( (last.end - first.start).total_seconds() )) - def compute_order(self, dates: 'Collection[OccasionDate] | None') -> int: + def compute_order(self, dates: Collection[OccasionDate] | None) -> int: if not dates: return -1 @@ -286,25 +288,25 @@ def compute_order(self, dates: 'Collection[OccasionDate] | None') -> int: def compute_active_days( self, - dates: 'Collection[OccasionDate] | None' + dates: Collection[OccasionDate] | None ) -> list[int]: return [day for date in (dates or ()) for day in date.active_days] def compute_weekdays( self, - dates: 'Collection[OccasionDate] | None' + dates: Collection[OccasionDate] | None ) -> list[int]: return list({day for date in (dates or ()) for day in date.weekdays}) @observes('dates') - def observe_dates(self, dates: 'Collection[OccasionDate] | None') -> None: + def observe_dates(self, dates: Collection[OccasionDate] | None) -> None: self.duration = self.compute_duration(dates) self.order = self.compute_order(dates) self.weekdays = self.compute_weekdays(dates) self.active_days = self.compute_active_days(dates) @validates('dates') - def validate_dates(self, key: str, date: 'OccasionDate') -> 'OccasionDate': + def validate_dates(self, key: str, date: OccasionDate) -> OccasionDate: for o in self.dates: if o.id != date.id: assert not sedate.overlaps( @@ -313,7 +315,7 @@ def validate_dates(self, key: str, date: 'OccasionDate') -> 'OccasionDate': return date @observes('needs') - def observe_needs(self, needs: 'Collection[OccasionNeed] | None') -> None: + def observe_needs(self, needs: Collection[OccasionNeed] | None) -> None: for need in (needs or ()): if need.accept_signups: self.seeking_volunteers = True @@ -341,7 +343,7 @@ def available_spots(self) -> int: return self.spots.upper - 1 - self.attendee_count @available_spots.expression # type:ignore[no-redef] - def available_spots(cls) -> 'ColumnElement[int]': + def available_spots(cls) -> ColumnElement[int]: return case(( ( cls.cancelled == False, @@ -402,13 +404,13 @@ def cancel(self) -> None: period = self.period if not period.confirmed: - def cancel(booking: 'Booking') -> None: + def cancel(booking: Booking) -> None: booking.state = 'cancelled' else: bookings = BookingCollection(object_session(self)) scoring = period.scoring - def cancel(booking: 'Booking') -> None: + def cancel(booking: Booking) -> None: bookings.cancel_booking(booking, scoring) for booking in self.bookings: diff --git a/src/onegov/activity/models/occasion_date.py b/src/onegov/activity/models/occasion_date.py index 1473d31d23..de452183f1 100644 --- a/src/onegov/activity/models/occasion_date.py +++ b/src/onegov/activity/models/occasion_date.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate from datetime import datetime, time @@ -38,7 +40,7 @@ def compute( localized_start: datetime, localized_end: datetime, total_seconds: float - ) -> 'DAYS': + ) -> DAYS: hours = total_seconds / 3600 if hours <= 6: @@ -70,24 +72,24 @@ def __hash__(self) -> int: return hash(self.id) #: the internal id of this occasion date - id: 'Column[int]' = Column(Integer, primary_key=True) + id: Column[int] = Column(Integer, primary_key=True) #: Timezone of the occasion date - timezone: 'Column[str]' = Column(Text, nullable=False) + timezone: Column[str] = Column(Text, nullable=False) #: The start of the range - start: 'Column[datetime]' = Column(UTCDateTime, nullable=False) + start: Column[datetime] = Column(UTCDateTime, nullable=False) #: The end of the range - end: 'Column[datetime]' = Column(UTCDateTime, nullable=False) + end: Column[datetime] = Column(UTCDateTime, nullable=False) #: The associated occasion - occasion_id: 'Column[uuid.UUID]' = Column( + occasion_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('occasions.id'), nullable=False ) - occasion: 'relationship[Occasion]' = relationship( + occasion: relationship[Occasion] = relationship( 'Occasion', back_populates='dates' ) @@ -105,7 +107,7 @@ def localized_end(self) -> datetime: return sedate.to_timezone(self.end, self.timezone) @property - def active_days(self) -> 'Iterator[int]': + def active_days(self) -> Iterator[int]: for dt in sedate.dtrange(self.localized_start, self.localized_end): yield dt.date().toordinal() @@ -135,17 +137,17 @@ def duration(self) -> DAYS: self.duration_in_seconds ) - def overlaps(self, other: 'OccasionDate') -> bool: + def overlaps(self, other: OccasionDate) -> bool: return sedate.overlaps(self.start, self.end, other.start, other.end) # # changes to the dates need to be propagated to the parent occasion -# # so it can update its aggreagated values -@event.listens_for(Session, 'before_flush') +# # so it can update its aggregated values +@event.listens_for(Session, 'before_flush') # type:ignore[misc] def before_flush( session: Session, - context: 'UOWTransaction', - instances: 'Sequence[Any]' + context: UOWTransaction, + instances: Sequence[Any] ) -> None: for obj in session.dirty: if isinstance(obj, OccasionDate): diff --git a/src/onegov/activity/models/occasion_need.py b/src/onegov/activity/models/occasion_need.py index 312829660f..15825429fc 100644 --- a/src/onegov/activity/models/occasion_need.py +++ b/src/onegov/activity/models/occasion_need.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -25,40 +27,40 @@ class OccasionNeed(Base, TimestampMixin): __tablename__ = 'occasion_needs' #: the public id of this occasion resource - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the name of the occasion resource - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: a description of the occasion resource - description: 'Column[str | None]' = Column(Text, nullable=True) + description: Column[str | None] = Column(Text, nullable=True) #: the required range of resources - number: 'Column[BoundedIntegerRange]' = Column(INT4RANGE, nullable=False) + number: Column[BoundedIntegerRange] = Column(INT4RANGE, nullable=False) #: true if volunteers may sign up for this - accept_signups: 'Column[bool]' = Column( + accept_signups: Column[bool] = Column( Boolean, nullable=False, default=False ) #: The associated occasion - occasion_id: 'Column[uuid.UUID]' = Column( + occasion_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('occasions.id'), nullable=False ) - occasion: 'relationship[Occasion]' = relationship( + occasion: relationship[Occasion] = relationship( 'Occasion', back_populates='needs' ) - volunteers: 'relationship[list[Volunteer]]' = relationship( + volunteers: relationship[list[Volunteer]] = relationship( 'Volunteer', back_populates='need', cascade='all, delete-orphan' diff --git a/src/onegov/activity/models/period.py b/src/onegov/activity/models/period.py index 3076ba38bc..c70a15a3f9 100644 --- a/src/onegov/activity/models/period.py +++ b/src/onegov/activity/models/period.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate from datetime import date, datetime @@ -213,7 +215,7 @@ def booking_limit(self) -> int | None: class PeriodMetaBase(NamedTuple): - id: 'uuid.UUID' + id: uuid.UUID title: str active: bool confirmed: bool @@ -228,7 +230,7 @@ class PeriodMetaBase(NamedTuple): execution_start: date execution_end: date max_bookings_per_attendee: int | None - booking_cost: 'Decimal | None' + booking_cost: Decimal | None all_inclusive: bool pay_organiser_directly: bool minutes_between: int | None @@ -250,7 +252,7 @@ class PeriodMeta(PeriodMetaBase, PeriodMixin): # a short TTL like 60 seconds. That would already avoid # the many redundant calls to `phase`. - def materialize(self, session: 'Session') -> 'Period': + def materialize(self, session: Session) -> Period: period = session.query(Period).get(self.id) assert period is not None return period @@ -269,88 +271,88 @@ class Period(Base, PeriodMixin, TimestampMixin): __tablename__ = 'periods' #: The public id of this period - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The public title of this period - title: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) #: Only one period is active at a time - active: 'Column[bool]' = Column(Boolean, nullable=False, default=False) + active: Column[bool] = Column(Boolean, nullable=False, default=False) #: A confirmed period may not be automatically matched anymore and all #: booking changes to it are communicated to the customer - confirmed: 'Column[bool]' = Column(Boolean, nullable=False, default=False) + confirmed: Column[bool] = Column(Boolean, nullable=False, default=False) #: A confirmable period has a prebooking phase, while an unconfirmable # booking does not. An unconfirmable booking starts as `confirmed` for # legacy reasons (even though it doesn't sound sane to have an # unconfirmable period that is confirmed). - confirmable: 'Column[bool]' = Column(Boolean, nullable=False, default=True) + confirmable: Column[bool] = Column(Boolean, nullable=False, default=True) #: A finalized period may not have any change in bookings anymore - finalized: 'Column[bool]' = Column(Boolean, nullable=False, default=False) + finalized: Column[bool] = Column(Boolean, nullable=False, default=False) #: A finalizable period may have invoices associated with it, an #: unfinalizable period may not - finalizable: 'Column[bool]' = Column(Boolean, nullable=False, default=True) + finalizable: Column[bool] = Column(Boolean, nullable=False, default=True) #: An archived period has been entirely completed - archived: 'Column[bool]' = Column(Boolean, nullable=False, default=False) + archived: Column[bool] = Column(Boolean, nullable=False, default=False) #: Start of the wishlist-phase - prebooking_start: 'Column[date]' = Column(Date, nullable=False) + prebooking_start: Column[date] = Column(Date, nullable=False) #: End of the wishlist-phase - prebooking_end: 'Column[date]' = Column(Date, nullable=False) + prebooking_end: Column[date] = Column(Date, nullable=False) #: Start of the booking-phase - booking_start: 'Column[date]' = Column(Date, nullable=False) + booking_start: Column[date] = Column(Date, nullable=False) #: End of the booking-phase - booking_end: 'Column[date]' = Column(Date, nullable=False) + booking_end: Column[date] = Column(Date, nullable=False) #: Date of the earliest possible occasion start of this period - execution_start: 'Column[date]' = Column(Date, nullable=False) + execution_start: Column[date] = Column(Date, nullable=False) #: Date of the latest possible occasion end of this period - execution_end: 'Column[date]' = Column(Date, nullable=False) + execution_end: Column[date] = Column(Date, nullable=False) #: Extra data stored on the period - data: 'Column[dict[str, Any]]' = Column(JSON, nullable=False, default=dict) + data: Column[dict[str, Any]] = Column(JSON, nullable=False, default=dict) #: Maximum number of bookings per attendee - max_bookings_per_attendee: 'Column[int | None]' = Column( + max_bookings_per_attendee: Column[int | None] = Column( Integer, nullable=True ) #: Base cost for one or many bookings - booking_cost: 'Column[Decimal | None]' = Column( + booking_cost: Column[Decimal | None] = Column( Numeric(precision=8, scale=2), nullable=True ) #: True if the booking cost is meant for all bookings in a period #: or for each single booking - all_inclusive: 'Column[bool]' = Column( + all_inclusive: Column[bool] = Column( Boolean, nullable=False, default=False ) #: True if the costs of an occasions need to be paid to the organiser - pay_organiser_directly: 'Column[bool]' = Column( + pay_organiser_directly: Column[bool] = Column( Boolean, nullable=False, default=False ) #: Time between bookings in minutes - minutes_between: 'Column[int | None]' = Column( + minutes_between: Column[int | None] = Column( Integer, nullable=True, default=0 @@ -358,7 +360,7 @@ class Period(Base, PeriodMixin, TimestampMixin): #: The alignment of bookings in the matching # FIXME: Restrict this to what is actually allowed i.e. Literal['day', ...] - alignment: 'Column[str | None]' = Column(Text, nullable=True) + alignment: Column[str | None] = Column(Text, nullable=True) #: Deadline for booking occasions. A deadline of 3 means that 3 days before #: an occasion is set to start, bookings are disabled. @@ -369,27 +371,27 @@ class Period(Base, PeriodMixin, TimestampMixin): #: Also, if deadline_days is None, bookings can't be created in a #: finalized period either, as deadline_days is a prerequisite for the #: book_finalized setting. - deadline_days: 'Column[int | None]' = Column(Integer, nullable=True) + deadline_days: Column[int | None] = Column(Integer, nullable=True) #: True if bookings can be created by normal users in finalized periods. #: The deadline_days are still applied for these normal users. #: Admins can always create bookings during any time, deadline_days and #: book_finalized are ignored. - book_finalized: 'Column[bool]' = Column( + book_finalized: Column[bool] = Column( Boolean, nullable=False, default=False ) #: Date after which no bookings can be canceled by a mere member - cancellation_date: 'Column[date | None]' = Column(Date, nullable=True) + cancellation_date: Column[date | None] = Column(Date, nullable=True) #: Days between the occasion and the cancellation (an alternative to #: the cancellation_date) - cancellation_days: 'Column[int | None]' = Column(Integer, nullable=True) + cancellation_days: Column[int | None] = Column(Integer, nullable=True) #: The age barrier implementation in use - age_barrier_type: 'Column[str]' = Column( + age_barrier_type: Column[str] = Column( Text, nullable=False, default='exact' @@ -420,24 +422,24 @@ class Period(Base, PeriodMixin, TimestampMixin): ) #: The occasions linked to this period - occasions: 'relationship[list[Occasion]]' = relationship( + occasions: relationship[list[Occasion]] = relationship( 'Occasion', order_by='Occasion.order', back_populates='period' ) #: The bookings linked to this period - bookings: 'relationship[list[Booking]]' = relationship( + bookings: relationship[list[Booking]] = relationship( 'Booking', back_populates='period' ) - invoices: 'relationship[list[Invoice]]' = relationship( + invoices: relationship[list[Invoice]] = relationship( 'Invoice', back_populates='period' ) - publication_requests: 'relationship[list[PublicationRequest]]' + publication_requests: relationship[list[PublicationRequest]] publication_requests = relationship( 'PublicationRequest', back_populates='period' @@ -530,7 +532,7 @@ def archive(self) -> None: session = object_session(self) - def future_periods() -> 'Iterator[uuid.UUID]': + def future_periods() -> Iterator[uuid.UUID]: p = session.query(Period) p = p.order_by(desc(Period.execution_start)) p = p.with_entities(Period.id) @@ -584,7 +586,7 @@ def confirm_and_start_booking_phase(self) -> None: self.booking_start = date.today() @property - def scoring(self) -> 'Scoring': + def scoring(self) -> Scoring: # circular import from onegov.activity.matching.score import Scoring @@ -593,8 +595,8 @@ def scoring(self) -> 'Scoring': session=object_session(self)) @scoring.setter - def scoring(self, scoring: 'Scoring') -> None: + def scoring(self, scoring: Scoring) -> None: self.data['match-settings'] = scoring.settings - def materialize(self, session: 'Session') -> 'Period': + def materialize(self, session: Session) -> Period: return self diff --git a/src/onegov/activity/models/publication_request.py b/src/onegov/activity/models/publication_request.py index 837cbb421d..3cb464f95e 100644 --- a/src/onegov/activity/models/publication_request.py +++ b/src/onegov/activity/models/publication_request.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -27,31 +29,31 @@ class PublicationRequest(Base, TimestampMixin): __tablename__ = 'publication_requests' #: The public id of the publication request - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The activity linked to this request - activity_id: 'Column[uuid.UUID]' = Column( + activity_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('activities.id'), nullable=False ) - activity: 'relationship[Activity]' = relationship( + activity: relationship[Activity] = relationship( 'Activity', back_populates='publication_requests', lazy='joined' ) #: The period linked to this request - period_id: 'Column[uuid.UUID]' = Column( + period_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('periods.id'), nullable=False ) - period: 'relationship[Period]' = relationship( + period: relationship[Period] = relationship( 'Period', back_populates='publication_requests', lazy='joined' diff --git a/src/onegov/activity/models/volunteer.py b/src/onegov/activity/models/volunteer.py index 0a025089fd..4cd198898e 100644 --- a/src/onegov/activity/models/volunteer.py +++ b/src/onegov/activity/models/volunteer.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import ContentMixin, TimestampMixin from onegov.core.orm.types import UUID @@ -30,14 +32,14 @@ class Volunteer(Base, ContentMixin, TimestampMixin): __tablename__ = 'volunteers' #: The id of the record, may be used publicly - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The state of the volunteer - state: 'Column[VolunteerState]' = Column( + state: Column[VolunteerState] = Column( Enum( # type:ignore[arg-type] 'open', 'contacted', @@ -49,47 +51,47 @@ class Volunteer(Base, ContentMixin, TimestampMixin): ) #: The need the volunteer signed up for - need_id: 'Column[uuid.UUID]' = Column( + need_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('occasion_needs.id'), nullable=False ) - need: 'relationship[OccasionNeed]' = relationship( + need: relationship[OccasionNeed] = relationship( 'OccasionNeed', back_populates='volunteers' ) #: A token linking multiple volunteer records (volunteers sign up for #: multiple needs at once, and are then multiplexed here) - token: 'Column[uuid.UUID]' = Column( + token: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] nullable=False, default=uuid4 ) #: The first name of the volunteer - first_name: 'Column[str]' = Column(Text, nullable=False) + first_name: Column[str] = Column(Text, nullable=False) #: The last name of the volunteer - last_name: 'Column[str]' = Column(Text, nullable=False) + last_name: Column[str] = Column(Text, nullable=False) #: The address of the volunteer - address: 'Column[str]' = Column(Text, nullable=False) + address: Column[str] = Column(Text, nullable=False) #: The zip code of the volunteer - zip_code: 'Column[str]' = Column(Text, nullable=False) + zip_code: Column[str] = Column(Text, nullable=False) #: The place of the volunteer - place: 'Column[str]' = Column(Text, nullable=False) + place: Column[str] = Column(Text, nullable=False) #: The organisation of the volunteer - organisation: 'Column[str | None]' = Column(Text, nullable=True) + organisation: Column[str | None] = Column(Text, nullable=True) #: The birth_date of the volunteer - birth_date: 'Column[date]' = Column(Date, nullable=False) + birth_date: Column[date] = Column(Date, nullable=False) #: The e-mail address of the volunteer - email: 'Column[str]' = Column(Text, nullable=False) + email: Column[str] = Column(Text, nullable=False) #: The phone number of the volunteer - phone: 'Column[str]' = Column(Text, nullable=False) + phone: Column[str] = Column(Text, nullable=False) diff --git a/src/onegov/activity/types.py b/src/onegov/activity/types.py index d73301d1f4..d5f59abaaa 100644 --- a/src/onegov/activity/types.py +++ b/src/onegov/activity/types.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from psycopg2.extras import NumericRange from typing import TYPE_CHECKING diff --git a/src/onegov/activity/upgrade.py b/src/onegov/activity/upgrade.py index c81bbee201..4336361e10 100644 --- a/src/onegov/activity/upgrade.py +++ b/src/onegov/activity/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + import hashlib import string diff --git a/src/onegov/activity/utils.py b/src/onegov/activity/utils.py index 7dfcf2def4..39ac053210 100644 --- a/src/onegov/activity/utils.py +++ b/src/onegov/activity/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import lxml import random import re @@ -59,16 +61,16 @@ def is_valid_group_code(code: str) -> bool: def overlaps( - range_a: 'RangeLike[SupportsRichComparisonT]', - range_b: 'RangeLike[SupportsRichComparisonT]' + range_a: RangeLike[SupportsRichComparisonT], + range_b: RangeLike[SupportsRichComparisonT] ) -> bool: return (range_b[0] <= range_a[0] <= range_b[1]) or ( # type:ignore range_a[0] <= range_b[0] <= range_a[1]) # type:ignore[operator] def merge_ranges( - ranges: 'Iterable[RangeTuple[SupportsRichComparisonT]]' -) -> list['RangeTuple[SupportsRichComparisonT]']: + ranges: Iterable[RangeTuple[SupportsRichComparisonT]] +) -> list[RangeTuple[SupportsRichComparisonT]]: """ Merges the given list of ranges into a list of ranges including only exclusive ranges. The ranges are turned into tuples to make them hashable. @@ -106,7 +108,7 @@ def num_range_decode(s: object) -> tuple[int, int] | None: return None -def num_range_encode(a: 'RangeLike[int]') -> str: +def num_range_encode(a: RangeLike[int]) -> str: return f'{a[0]}-{a[1]}' @@ -122,11 +124,11 @@ def date_range_decode(s: object) -> tuple[date, date] | None: return date.fromisoformat(s), date.fromisoformat(e) -def date_range_encode(d: 'RangeLike[date]') -> str: +def date_range_encode(d: RangeLike[date]) -> str: return ':'.join((d[0].strftime('%Y-%m-%d'), d[1].strftime('%Y-%m-%d'))) -def generate_xml(payments: 'Iterable[dict[str, Any]]') -> str: +def generate_xml(payments: Iterable[dict[str, Any]]) -> str: """ Creates an xml for import through ISO20022. Used for testing only. """ transactions = [] @@ -191,8 +193,8 @@ def generate_xml(payments: 'Iterable[dict[str, Any]]') -> str: def dates_overlap( - a: 'Iterable[RangeTuple[datetime]]', - b: 'Iterable[RangeTuple[datetime]]', + a: Iterable[RangeTuple[datetime]], + b: Iterable[RangeTuple[datetime]], minutes_between: float = 0, cut_end: bool = True, alignment: Literal['day', 'week', 'month'] | None = None @@ -237,7 +239,7 @@ def dates_overlap( return False -def is_internal_image(url: str | None) -> 'TypeGuard[str]': +def is_internal_image(url: str | None) -> TypeGuard[str]: return url and INTERNAL_IMAGE_EX.match(url) and True or False diff --git a/src/onegov/agency/__init__.py b/src/onegov/agency/__init__.py index d799e08379..648c24f34b 100644 --- a/src/onegov/agency/__init__.py +++ b/src/onegov/agency/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.agency') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/agency/api.py b/src/onegov/agency/api.py index 5cfc52becf..175ad5d183 100644 --- a/src/onegov/agency/api.py +++ b/src/onegov/agency/api.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from dateutil.parser import isoparse from functools import cached_property from onegov.agency.collections import ExtendedPersonCollection @@ -34,8 +36,8 @@ def filter_for_updated( filter_operation: str, filter_value: str | None, - result: 'T' -) -> 'T': + result: T +) -> T: """ Applies filters for several 'updated' comparisons. Refer to UPDATE_FILTER_PARAMS for all filter keywords. @@ -62,27 +64,27 @@ def filter_for_updated( class ApisMixin: - app: 'AgencyApp' + app: AgencyApp @cached_property - def agency_api(self) -> 'AgencyApiEndpoint': + def agency_api(self) -> AgencyApiEndpoint: return AgencyApiEndpoint(self.app) @cached_property - def person_api(self) -> 'PersonApiEndpoint': + def person_api(self) -> PersonApiEndpoint: return PersonApiEndpoint(self.app) @cached_property - def membership_api(self) -> 'MembershipApiEndpoint': + def membership_api(self) -> MembershipApiEndpoint: return MembershipApiEndpoint(self.app) -def get_geo_location(item: 'ContentMixin') -> dict[str, Any]: +def get_geo_location(item: ContentMixin) -> dict[str, Any]: geo = item.content.get('coordinates', Coordinates()) or Coordinates() return {'lon': geo.lon, 'lat': geo.lat, 'zoom': geo.zoom} -def get_modified_iso_format(item: 'TimestampMixin') -> str: +def get_modified_iso_format(item: TimestampMixin) -> str: """ Returns the iso format of the modified or created field of item. @@ -93,7 +95,7 @@ def get_modified_iso_format(item: 'TimestampMixin') -> str: class PersonApiEndpoint(ApiEndpoint['ExtendedPerson'], ApisMixin): - app: 'AgencyApp' + app: AgencyApp endpoint = 'people' filters = {'first_name', 'last_name'} | UPDATE_FILTER_PARAMS form_class = PersonMutationForm @@ -122,7 +124,7 @@ def collection(self) -> ExtendedPersonCollection: result.batch_size = self.batch_size return result - def item_data(self, item: 'ExtendedPerson') -> dict[str, Any]: + def item_data(self, item: ExtendedPerson) -> dict[str, Any]: data = { attribute: getattr(item, attribute, None) for attribute in ( @@ -152,7 +154,7 @@ def item_data(self, item: 'ExtendedPerson') -> dict[str, Any]: data['modified'] = get_modified_iso_format(item) return data - def item_links(self, item: 'ExtendedPerson') -> dict[str, Any]: + def item_links(self, item: ExtendedPerson) -> dict[str, Any]: result = { attribute: getattr(item, attribute, None) for attribute in ( @@ -168,7 +170,7 @@ def item_links(self, item: 'ExtendedPerson') -> dict[str, Any]: def apply_changes( self, - item: 'ExtendedPerson', + item: ExtendedPerson, form: PersonMutationForm ) -> None: @@ -178,7 +180,7 @@ def apply_changes( class AgencyApiEndpoint(ApiEndpoint['ExtendedAgency'], ApisMixin): - app: 'AgencyApp' + app: AgencyApp endpoint = 'agencies' filters = {'parent', 'title'} | UPDATE_FILTER_PARAMS @@ -205,7 +207,7 @@ def collection(self) -> PaginatedAgencyCollection: result.batch_size = self.batch_size return result - def item_data(self, item: 'ExtendedAgency') -> dict[str, Any]: + def item_data(self, item: ExtendedAgency) -> dict[str, Any]: return { 'title': item.title, 'portrait': item.portrait, @@ -222,7 +224,7 @@ def item_data(self, item: 'ExtendedAgency') -> dict[str, Any]: 'geo_location': get_geo_location(item), } - def item_links(self, item: 'ExtendedAgency') -> dict[str, Any]: + def item_links(self, item: ExtendedAgency) -> dict[str, Any]: return { 'organigram': item.organigram, 'parent': self.for_item(item.parent), @@ -238,7 +240,7 @@ class MembershipApiEndpoint( ApisMixin ): - app: 'AgencyApp' + app: AgencyApp endpoint = 'memberships' filters = {'agency', 'person'} | UPDATE_FILTER_PARAMS @@ -263,13 +265,13 @@ def collection(self) -> PaginatedMembershipCollection: result.batch_size = self.batch_size return result - def item_data(self, item: 'ExtendedAgencyMembership') -> dict[str, Any]: + def item_data(self, item: ExtendedAgencyMembership) -> dict[str, Any]: return { 'title': item.title, 'modified': get_modified_iso_format(item), } - def item_links(self, item: 'ExtendedAgencyMembership') -> dict[str, Any]: + def item_links(self, item: ExtendedAgencyMembership) -> dict[str, Any]: return { 'agency': self.agency_api.for_item(item.agency), 'person': self.person_api.for_item(item.person) diff --git a/src/onegov/agency/app.py b/src/onegov/agency/app.py index db462017af..a1f114cee1 100644 --- a/src/onegov/agency/app.py +++ b/src/onegov/agency/app.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency.api import AgencyApiEndpoint from onegov.agency.api import MembershipApiEndpoint from onegov.agency.api import PersonApiEndpoint @@ -51,13 +53,13 @@ def people_xlsx_exists(self) -> bool: return self.filestorage.exists('people.xlsx') @property - def root_pdf_modified(self) -> 'datetime | None': + def root_pdf_modified(self) -> datetime | None: if self.root_pdf_exists: return self.filestorage.getdetails('root.pdf').modified return None @property - def people_xlsx_modified(self) -> 'datetime | None': + def people_xlsx_modified(self) -> datetime | None: if self.people_xlsx: return self.filestorage.getdetails('people.xlsx').modified return None @@ -73,7 +75,7 @@ def root_pdf(self) -> bytes | None: # FIXME: asymmetric property @root_pdf.setter - def root_pdf(self, value: 'SupportsRead[bytes] | bytes') -> None: + def root_pdf(self, value: SupportsRead[bytes] | bytes) -> None: with self.filestorage.open('root.pdf', 'wb') as file: if hasattr(value, 'read'): value = value.read() @@ -91,7 +93,7 @@ def people_xlsx(self) -> bytes | None: # FIXME: asymmetric property @people_xlsx.setter - def people_xlsx(self, value: 'SupportsRead[bytes] | bytes') -> None: + def people_xlsx(self, value: SupportsRead[bytes] | bytes) -> None: with self.filestorage.open('people.xlsx', 'wb') as file: if hasattr(value, 'read'): value = value.read() @@ -120,7 +122,7 @@ def enable_yubikey(self, value: bool) -> None: @AgencyApp.setting(section='org', name='create_new_organisation') def get_create_new_organisation_factory( -) -> 'Callable[[AgencyApp, str], Organisation]': +) -> Callable[[AgencyApp, str], Organisation]: return create_new_organisation @@ -130,7 +132,7 @@ def get_template_directory() -> str: @AgencyApp.template_variables() -def get_template_variables(request: AgencyRequest) -> 'RenderData': +def get_template_variables(request: AgencyRequest) -> RenderData: return { 'global_tools': tuple(get_global_tools(request)), 'top_navigation': tuple(get_top_navigation(request)), @@ -174,29 +176,29 @@ def get_js_path() -> str: @AgencyApp.webasset('people-select') -def get_people_select_asset() -> 'Iterator[str]': +def get_people_select_asset() -> Iterator[str]: yield 'people-select.js' @AgencyApp.webasset('sortable-multi-checkbox') -def get_sortable_multi_checkbox_asset() -> 'Iterator[str]': +def get_sortable_multi_checkbox_asset() -> Iterator[str]: yield 'jquery.js' yield 'sortable.js' yield 'sortable-multi-checkbox.js' @AgencyApp.webasset('redactor', filters={'js': None}) -def get_redactor_asserts() -> 'Iterator[str]': +def get_redactor_asserts() -> Iterator[str]: yield from redactor_assets() @AgencyApp.webasset('editor') -def get_editor_assets() -> 'Iterator[str]': +def get_editor_assets() -> Iterator[str]: yield from editor_assets() @AgencyApp.setting(section='api', name='endpoints') -def get_api_endpoints() -> list[type['ApiEndpoint[Any]']]: +def get_api_endpoints() -> list[type[ApiEndpoint[Any]]]: return [ AgencyApiEndpoint, PersonApiEndpoint, diff --git a/src/onegov/agency/cli.py b/src/onegov/agency/cli.py index 70a0b9922a..748a529b07 100644 --- a/src/onegov/agency/cli.py +++ b/src/onegov/agency/cli.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import click import transaction @@ -33,14 +35,14 @@ def consolidate_cli( ignore_case: bool, dry_run: bool, verbose: bool -) -> 'Callable[[AgencyRequest, AgencyApp], None]': +) -> Callable[[AgencyRequest, AgencyApp], None]: """ Consolidates double entries of person objects based on the property `based_on`. Property must be convertible to string. """ buffer = 100 - def find_double_entries(session: 'Session') -> tuple[ + def find_double_entries(session: Session) -> tuple[ dict[str, ExtendedPerson], dict[str, list[ExtendedPerson]] ]: @@ -89,7 +91,7 @@ def consolidate_persons( return person def consolidate_memberships( - session: 'Session', + session: Session, person: ExtendedPerson, persons: list[ExtendedPerson] ) -> None: @@ -100,7 +102,7 @@ def consolidate_memberships( session.flush() session.delete(p) - def do_consolidate(request: 'AgencyRequest', app: 'AgencyApp') -> None: + def do_consolidate(request: AgencyRequest, app: AgencyApp) -> None: session = request.session first_seen, to_consolidate = find_double_entries(session) print(f'Double entries found based on ' @@ -131,9 +133,9 @@ def import_bs_function( agency_file: str, people_file: str, dry_run: bool -) -> 'Callable[[AgencyRequest, AgencyApp], None]': +) -> Callable[[AgencyRequest, AgencyApp], None]: - def execute(request: 'AgencyRequest', app: 'AgencyApp') -> None: + def execute(request: AgencyRequest, app: AgencyApp) -> None: import_membership_titles(agency_file, people_file, request, app) total_empty_titles = 0 @@ -162,7 +164,7 @@ def import_bs_data_files( people_file: str, dry_run: bool, clean: bool -) -> 'Callable[[AgencyRequest, AgencyApp], None]': +) -> Callable[[AgencyRequest, AgencyApp], None]: """ Usage: @@ -173,7 +175,7 @@ def import_bs_data_files( buffer = 100 - def execute(request: 'AgencyRequest', app: 'AgencyApp') -> None: + def execute(request: AgencyRequest, app: AgencyApp) -> None: if clean: session = request.session @@ -222,7 +224,7 @@ def import_lu_data_files( data_file: str, dry_run: bool, clean: bool -) -> 'Callable[[AgencyRequest, AgencyApp], None]': +) -> Callable[[AgencyRequest, AgencyApp], None]: """ Usage: @@ -232,7 +234,7 @@ def import_lu_data_files( buffer = 100 - def execute(request: 'AgencyRequest', app: 'AgencyApp') -> None: + def execute(request: AgencyRequest, app: AgencyApp) -> None: if clean: session = request.session @@ -274,12 +276,12 @@ def execute(request: 'AgencyRequest', app: 'AgencyApp') -> None: @click.option('--root/--no-root', default=True) @click.option('--recursive/--no-recursive', default=True) def create_pdf( - group_context: 'GroupContext', + group_context: GroupContext, root: bool, recursive: bool -) -> 'Callable[[AgencyRequest, AgencyApp], None]': +) -> Callable[[AgencyRequest, AgencyApp], None]: - def _create_pdf(request: 'AgencyRequest', app: 'AgencyApp') -> None: + def _create_pdf(request: AgencyRequest, app: AgencyApp) -> None: session = app.session() agencies = ExtendedAgencyCollection(session) @@ -321,11 +323,11 @@ def _create_pdf(request: 'AgencyRequest', app: 'AgencyApp') -> None: @pass_group_context @click.option('--people', default=True, is_flag=True) def export_xlsx( - group_context: 'GroupContext', + group_context: GroupContext, people: bool -) -> 'Callable[[AgencyRequest, AgencyApp], None]': +) -> Callable[[AgencyRequest, AgencyApp], None]: - def _export_xlsx(request: 'AgencyRequest', app: 'AgencyApp') -> None: + def _export_xlsx(request: AgencyRequest, app: AgencyApp) -> None: session = app.session() if people: xlsx = export_person_xlsx(session) @@ -338,10 +340,10 @@ def _export_xlsx(request: 'AgencyRequest', app: 'AgencyApp') -> None: @cli.command('enable-yubikey') @pass_group_context def enable_yubikey( - group_context: 'GroupContext' -) -> 'Callable[[AgencyRequest, AgencyApp], None]': + group_context: GroupContext +) -> Callable[[AgencyRequest, AgencyApp], None]: - def _enable_yubikey(request: 'AgencyRequest', app: 'AgencyApp') -> None: + def _enable_yubikey(request: AgencyRequest, app: AgencyApp) -> None: if app.org: app.org.meta['enable_yubikey'] = True click.secho('YubiKey enabled', fg='green') @@ -352,10 +354,10 @@ def _enable_yubikey(request: 'AgencyRequest', app: 'AgencyApp') -> None: @cli.command('disable-yubikey') @pass_group_context def disable_yubikey( - group_context: 'GroupContext' -) -> 'Callable[[AgencyRequest, AgencyApp], None]': + group_context: GroupContext +) -> Callable[[AgencyRequest, AgencyApp], None]: - def _disable_yubikey(request: 'AgencyRequest', app: 'AgencyApp') -> None: + def _disable_yubikey(request: AgencyRequest, app: AgencyApp) -> None: if app.org: app.org.meta['enable_yubikey'] = False click.secho('YubiKey disabled', fg='green') diff --git a/src/onegov/agency/collections/__init__.py b/src/onegov/agency/collections/__init__.py index 5281496a10..8275c76435 100644 --- a/src/onegov/agency/collections/__init__.py +++ b/src/onegov/agency/collections/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency.collections.agencies import ExtendedAgencyCollection from onegov.agency.collections.agencies import PaginatedAgencyCollection from onegov.agency.collections.memberships import PaginatedMembershipCollection diff --git a/src/onegov/agency/collections/agencies.py b/src/onegov/agency/collections/agencies.py index 2fb3b4cbc8..91d6ae8723 100644 --- a/src/onegov/agency/collections/agencies.py +++ b/src/onegov/agency/collections/agencies.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency.models import ExtendedAgency from onegov.agency.utils import filter_modified_or_created from onegov.core.collection import GenericCollection, Pagination @@ -32,7 +34,7 @@ class ExtendedAgencyCollection(AdjacencyListCollection[ExtendedAgency]): # Used to create link for root pdf based on timestamp def __init__( self, - session: 'Session', + session: Session, # FIXME: These really should be float/int, we just need to add # convertes to the path configuration... root_pdf_modified: str | None = None, @@ -50,18 +52,18 @@ class PaginatedAgencyCollection( def __init__( self, - session: 'Session', + session: Session, page: int = 0, parent: str | Literal[False] | None = None, exclude_hidden: bool = True, - joinedload: 'Collection[str] | None' = None, + joinedload: Collection[str] | None = None, title: str | None = None, updated_gt: str | None = None, updated_ge: str | None = None, updated_eq: str | None = None, updated_le: str | None = None, updated_lt: str | None = None, - undefer: 'Collection[str] | None' = None + undefer: Collection[str] | None = None ) -> None: super().__init__(session) @@ -90,7 +92,7 @@ def __eq__(self, other: object) -> bool: and other.parent == self.parent ) - def subset(self) -> 'Query[ExtendedAgency]': + def subset(self) -> Query[ExtendedAgency]: return self.query() @property @@ -109,7 +111,7 @@ def page_by_index(self, index: int) -> Self: updated_lt=self.updated_lt, ) - def for_filter(self, **kwargs: 'Unpack[FilterParams]') -> Self: + def for_filter(self, **kwargs: Unpack[FilterParams]) -> Self: return self.__class__( session=self.session, title=kwargs.get('title', self.title), @@ -120,7 +122,7 @@ def for_filter(self, **kwargs: 'Unpack[FilterParams]') -> Self: updated_lt=kwargs.get('updated_lt', self.updated_lt), ) - def query(self) -> 'Query[ExtendedAgency]': + def query(self) -> Query[ExtendedAgency]: query = super().query() for attribute in self.undefer: diff --git a/src/onegov/agency/collections/memberships.py b/src/onegov/agency/collections/memberships.py index 6829d96d38..bad0dc8a70 100644 --- a/src/onegov/agency/collections/memberships.py +++ b/src/onegov/agency/collections/memberships.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency.models import ExtendedAgency from onegov.agency.models import ExtendedAgencyMembership from onegov.agency.models import ExtendedPerson @@ -31,7 +33,7 @@ class PaginatedMembershipCollection( def __init__( self, - session: 'Session', + session: Session, page: int = 0, agency: str | None = None, person: str | None = None, @@ -67,7 +69,7 @@ def __eq__(self, other: object) -> bool: and other.person == self.person ) - def subset(self) -> 'Query[ExtendedAgencyMembership]': + def subset(self) -> Query[ExtendedAgencyMembership]: return self.query() @property @@ -85,7 +87,7 @@ def page_by_index(self, index: int) -> Self: updated_lt=self.updated_lt, ) - def for_filter(self, **kwargs: 'Unpack[FilterParams]') -> Self: + def for_filter(self, **kwargs: Unpack[FilterParams]) -> Self: return self.__class__( session=self.session, updated_gt=kwargs.get('updated_gt', self.updated_gt), @@ -95,7 +97,7 @@ def for_filter(self, **kwargs: 'Unpack[FilterParams]') -> Self: updated_lt=kwargs.get('updated_lt', self.updated_lt), ) - def query(self) -> 'Query[ExtendedAgencyMembership]': + def query(self) -> Query[ExtendedAgencyMembership]: query = super().query() if self.exclude_hidden: diff --git a/src/onegov/agency/collections/people.py b/src/onegov/agency/collections/people.py index 785b9484c3..2c6ac62018 100644 --- a/src/onegov/agency/collections/people.py +++ b/src/onegov/agency/collections/people.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.agency.models import ExtendedPerson @@ -48,7 +50,7 @@ def model_class(self) -> type[ExtendedPerson]: def __init__( self, - session: 'Session', + session: Session, page: int = 0, letter: str | None = None, agency: str | None = None, @@ -81,7 +83,7 @@ def __init__( # Usage for link generation of people excel based on timestamp self.xlsx_modified = xlsx_modified - def subset(self) -> 'Query[ExtendedPerson]': + def subset(self) -> Query[ExtendedPerson]: return self.query() def __eq__(self, other: object) -> bool: @@ -107,7 +109,7 @@ def page_by_index(self, page: int) -> Self: updated_lt=self.updated_lt, ) - def for_filter(self, **kwargs: 'Unpack[FilterParams]') -> Self: + def for_filter(self, **kwargs: Unpack[FilterParams]) -> Self: return self.__class__( session=self.session, letter=kwargs.get('letter', self.letter), @@ -121,7 +123,7 @@ def for_filter(self, **kwargs: 'Unpack[FilterParams]') -> Self: updated_lt=kwargs.get('updated_lt', self.updated_lt), ) - def query(self) -> 'Query[ExtendedPerson]': + def query(self) -> Query[ExtendedPerson]: query = self.session.query(ExtendedPerson) if self.exclude_hidden: query = query.filter( diff --git a/src/onegov/agency/custom.py b/src/onegov/agency/custom.py index 0fddb8fd78..bb5955a9c1 100644 --- a/src/onegov/agency/custom.py +++ b/src/onegov/agency/custom.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency import _ from onegov.agency.collections import ExtendedAgencyCollection from onegov.agency.collections import ExtendedPersonCollection @@ -14,7 +16,7 @@ from onegov.core.elements import LinkGroup -def get_global_tools(request: 'AgencyRequest') -> 'Iterator[Link | LinkGroup]': +def get_global_tools(request: AgencyRequest) -> Iterator[Link | LinkGroup]: for item in get_global_tools_base(request): title = getattr(item, 'title', None) @@ -29,7 +31,7 @@ def get_global_tools(request: 'AgencyRequest') -> 'Iterator[Link | LinkGroup]': yield item -def get_top_navigation(request: 'AgencyRequest') -> 'Iterator[Link]': +def get_top_navigation(request: AgencyRequest) -> Iterator[Link]: yield Link( text=_('People'), url=request.class_link(ExtendedPersonCollection) diff --git a/src/onegov/agency/data_import.py b/src/onegov/agency/data_import.py index 07814eb1d9..bf9d5d0489 100644 --- a/src/onegov/agency/data_import.py +++ b/src/onegov/agency/data_import.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import defaultdict from datetime import datetime @@ -33,10 +35,10 @@ def with_open( - func: 'Callable[[CSVFile[DefaultRow], *Ts], T]' -) -> 'Callable[[StrOrBytesPath, *Ts], T]': + func: Callable[[CSVFile[DefaultRow], *Ts], T] +) -> Callable[[StrOrBytesPath, *Ts], T]: - def _read(filename: 'StrOrBytesPath', *args: *Ts) -> T: + def _read(filename: StrOrBytesPath, *args: *Ts) -> T: with open(filename, 'rb') as f: file = CSVFile( f, @@ -55,8 +57,8 @@ def v_(string: str | None) -> str | None: def cleaned( - func: 'Callable[[str], T]' -) -> 'Callable[[str | None], T | None]': + func: Callable[[str], T] +) -> Callable[[str | None], T | None]: def clean(string: str | None) -> T | None: cleaned = v_(string) @@ -98,7 +100,7 @@ def split_address_on_new_line( return new_addr -def get_address(line: 'DefaultRow') -> Markup | None: +def get_address(line: DefaultRow) -> Markup | None: stao_addr, post_addr = v_(line.standortadresse), v_(line.postadresse) if stao_addr and post_addr: if stao_addr == post_addr: @@ -114,7 +116,7 @@ def get_address(line: 'DefaultRow') -> Markup | None: return None -def get_agency_portrait(line: 'DefaultRow') -> Markup | None: +def get_agency_portrait(line: DefaultRow) -> Markup | None: portrait = Markup('') address = get_address(line) if address: @@ -154,10 +156,10 @@ def get_agency_portrait(line: 'DefaultRow') -> Markup | None: @with_open def import_bs_agencies( - csvfile: CSVFile['DefaultRow'], - session: 'Session', - app: 'AgencyApp' -) -> dict[str, 'ExtendedAgency']: + csvfile: CSVFile[DefaultRow], + session: Session, + app: AgencyApp +) -> dict[str, ExtendedAgency]: agencies = ExtendedAgencyCollection(session) lines_by_id = {line.verzorgeinheitid: line for line in csvfile.lines} @@ -188,9 +190,9 @@ def import_bs_agencies( children[parent_id].append(basisid) def parse_agency( - line: 'DefaultRow', - parent: 'ExtendedAgency | None' = None - ) -> 'ExtendedAgency': + line: DefaultRow, + parent: ExtendedAgency | None = None + ) -> ExtendedAgency: portrait = get_agency_portrait(line) agency = agencies.add( @@ -206,7 +208,7 @@ def parse_agency( def add_children( basisid: str, - parent: 'ExtendedAgency | None' = None + parent: ExtendedAgency | None = None ) -> None: nonlocal added_count @@ -226,21 +228,21 @@ def add_children( @with_open def import_bs_persons( - csvfile: CSVFile['DefaultRow'], - agencies: 'Mapping[str, ExtendedAgency]', - session: 'Session', - app: 'AgencyApp' -) -> list['ExtendedPerson']: + csvfile: CSVFile[DefaultRow], + agencies: Mapping[str, ExtendedAgency], + session: Session, + app: AgencyApp +) -> list[ExtendedPerson]: people = ExtendedPersonCollection(session) persons = [] - def parse_date(date_string: str | None) -> 'date | None': + def parse_date(date_string: str | None) -> date | None: if not date_string: return None return datetime.strptime(date_string, '%d.%m.%Y').date() - def parse_person(line: 'DefaultRow') -> None: + def parse_person(line: DefaultRow) -> None: bemerkung = v_(line.bemerkung) notiz = v_(line.notiz) sprechstunde = v_(line.sprechstunde) @@ -295,11 +297,11 @@ def parse_person(line: 'DefaultRow') -> None: def import_bs_data( - agency_file: 'StrOrBytesPath', - person_file: 'StrOrBytesPath', - request: 'AgencyRequest', - app: 'AgencyApp' -) -> tuple[dict[str, 'ExtendedAgency'], list['ExtendedPerson']]: + agency_file: StrOrBytesPath, + person_file: StrOrBytesPath, + request: AgencyRequest, + app: AgencyApp +) -> tuple[dict[str, ExtendedAgency], list[ExtendedPerson]]: session = request.session agencies = import_bs_agencies(agency_file, session, app) @@ -334,7 +336,7 @@ def get_web_address(internet_adresse: str) -> str | None: return f'http://{internet_adresse}' -def get_email(line: 'DefaultRow') -> str | None: +def get_email(line: DefaultRow) -> str | None: email = v_(line.e_mail_adresse) if not email: @@ -360,7 +362,7 @@ def get_email(line: 'DefaultRow') -> str | None: return None -def check_skip(line: 'DefaultRow') -> bool: +def check_skip(line: DefaultRow) -> bool: if line.department == 'zNeu': return True @@ -378,7 +380,7 @@ def check_skip(line: 'DefaultRow') -> bool: return False -def check_skip_people(line: 'DefaultRow') -> bool: +def check_skip_people(line: DefaultRow) -> bool: kw_1 = 'Telefon' kw_2 = 'Telefonist' @@ -394,14 +396,14 @@ def check_skip_people(line: 'DefaultRow') -> bool: return False -def agency_id_agency_lu(words: 'Iterable[Any]') -> str: +def agency_id_agency_lu(words: Iterable[Any]) -> str: """ Generates an agency id based on each organisation and sub organisation word """ return '__'.join(str(word).lower() for word in words if word) -def agency_id_person_lu(line: 'DefaultRow') -> str: +def agency_id_person_lu(line: DefaultRow) -> str: """ Generates an agency id based on each organisation and sub organisation name for a person. @@ -413,16 +415,16 @@ def agency_id_person_lu(line: 'DefaultRow') -> str: @with_open def import_lu_people( - csvfile: CSVFile['DefaultRow'], - agencies: 'Mapping[str, ExtendedAgency]', - session: 'Session', - app: 'AgencyApp' -) -> list['ExtendedPerson']: + csvfile: CSVFile[DefaultRow], + agencies: Mapping[str, ExtendedAgency], + session: Session, + app: AgencyApp +) -> list[ExtendedPerson]: people = ExtendedPersonCollection(session) persons = [] - def parse_person(line: 'DefaultRow') -> None: + def parse_person(line: DefaultRow) -> None: vorname = v_(line.vorname) or '' if vorname and vorname[-1].isdigit(): @@ -450,8 +452,8 @@ def parse_person(line: 'DefaultRow') -> None: parse_membership(line, person, function) def parse_membership( - line: 'DefaultRow', - person: 'ExtendedPerson', + line: DefaultRow, + person: ExtendedPerson, function: str ) -> None: agency_id = agency_id_person_lu(line) @@ -483,10 +485,10 @@ def parse_membership( @with_open def import_lu_agencies( - csvfile: CSVFile['DefaultRow'], - session: 'Session', - app: 'AgencyApp' -) -> dict[str, 'ExtendedAgency']: + csvfile: CSVFile[DefaultRow], + session: Session, + app: AgencyApp +) -> dict[str, ExtendedAgency]: added_agencies = {} agencies = ExtendedAgencyCollection(session) @@ -606,10 +608,10 @@ def import_lu_agencies( def import_lu_data( - data_file: 'StrOrBytesPath', - request: 'AgencyRequest', - app: 'AgencyApp' -) -> tuple[dict[str, 'ExtendedAgency'], list['ExtendedPerson']]: + data_file: StrOrBytesPath, + request: AgencyRequest, + app: AgencyApp +) -> tuple[dict[str, ExtendedAgency], list[ExtendedPerson]]: session = request.session agencies = import_lu_agencies(data_file, session, app) @@ -619,7 +621,7 @@ def import_lu_data( @with_open -def parse_agencies(csvfile: CSVFile['DefaultRow']) -> dict[str, str]: +def parse_agencies(csvfile: CSVFile[DefaultRow]) -> dict[str, str]: lines_by_id = {line.verzorgeinheitid: line for line in csvfile.lines} treat_as_root = tuple( line.verzorgeinheitid for line in csvfile.lines @@ -643,10 +645,10 @@ def parse_agencies(csvfile: CSVFile['DefaultRow']) -> dict[str, str]: @with_open def match_person_membership_title( - csvfile: CSVFile['DefaultRow'], - agencies: 'Mapping[str, str]', - request: 'AgencyRequest', - app: 'AgencyApp' + csvfile: CSVFile[DefaultRow], + agencies: Mapping[str, str], + request: AgencyRequest, + app: AgencyApp ) -> None: session = request.session @@ -659,7 +661,7 @@ def match_person_membership_title( agency_by_name_not_found = [] updated_memberships = [] - def find_persons(line: 'DefaultRow') -> list['ExtendedPerson']: + def find_persons(line: DefaultRow) -> list[ExtendedPerson]: nonlocal person_not_found email = v_(line.email) @@ -681,12 +683,12 @@ def find_persons(line: 'DefaultRow') -> list['ExtendedPerson']: person_not_found.append(f'{email}, {fn} {ln}') return persons - def get_agencies_by_name(name: str) -> list['ExtendedAgency']: + def get_agencies_by_name(name: str) -> list[ExtendedAgency]: return agency_coll.query().filter_by(title=name).all() def match_membership_title( - line: 'DefaultRow', - agencies: 'Mapping[str, str]' + line: DefaultRow, + agencies: Mapping[str, str] ) -> None: nonlocal agency_by_name_not_found @@ -707,7 +709,7 @@ def match_membership_title( return def set_membership_title( - membership: 'AgencyMembership', + membership: AgencyMembership, name: str | None ) -> None: nonlocal updated_memberships @@ -766,10 +768,10 @@ def set_membership_title( def import_membership_titles( - agency_file: 'StrOrBytesPath', - person_file: 'StrOrBytesPath', - request: 'AgencyRequest', - app: 'AgencyApp' + agency_file: StrOrBytesPath, + person_file: StrOrBytesPath, + request: AgencyRequest, + app: AgencyApp ) -> None: agencies = parse_agencies(agency_file) diff --git a/src/onegov/agency/excel_export.py b/src/onegov/agency/excel_export.py index da52aa57d4..901464de30 100644 --- a/src/onegov/agency/excel_export.py +++ b/src/onegov/agency/excel_export.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from io import BytesIO @@ -35,7 +37,7 @@ ) -def extract_person_data(session: 'Session') -> list[dict[str, object]]: +def extract_person_data(session: Session) -> list[dict[str, object]]: collection = ExtendedPersonCollection(session) collection.exclude_hidden = False query = collection.query().outerjoin(ExtendedPerson.memberships) @@ -56,7 +58,7 @@ def extract_person_data(session: 'Session') -> list[dict[str, object]]: return write_out -def export_person_xlsx(session: 'Session') -> BytesIO: +def export_person_xlsx(session: Session) -> BytesIO: """ Exports every person with their memberships in xlsx format. """ file = BytesIO() workbook = Workbook(file, {'default_date_format': 'dd.mm.yyyy'}) diff --git a/src/onegov/agency/forms/__init__.py b/src/onegov/agency/forms/__init__.py index 9cc54295ab..c4360dddf3 100644 --- a/src/onegov/agency/forms/__init__.py +++ b/src/onegov/agency/forms/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency.forms.agency import ExtendedAgencyForm from onegov.agency.forms.agency import MoveAgencyForm from onegov.agency.forms.membership import MembershipForm diff --git a/src/onegov/agency/forms/agency.py b/src/onegov/agency/forms/agency.py index 08edfd688e..b80029ee0a 100644 --- a/src/onegov/agency/forms/agency.py +++ b/src/onegov/agency/forms/agency.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from cgi import FieldStorage from io import BytesIO diff --git a/src/onegov/agency/forms/membership.py b/src/onegov/agency/forms/membership.py index 075a71f1f9..745b08b9dc 100644 --- a/src/onegov/agency/forms/membership.py +++ b/src/onegov/agency/forms/membership.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency import _ from onegov.agency.collections import ExtendedPersonCollection from onegov.agency.models import ExtendedPerson @@ -17,7 +19,7 @@ _T = TypeVar('_T') -def duplicates(iterable: 'Iterable[_T]') -> set['_T']: +def duplicates(iterable: Iterable[_T]) -> set[_T]: items = set() duplicates = set() for item in iterable: diff --git a/src/onegov/agency/forms/mutation.py b/src/onegov/agency/forms/mutation.py index 7fe3a1db49..055461d672 100644 --- a/src/onegov/agency/forms/mutation.py +++ b/src/onegov/agency/forms/mutation.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency import _ from onegov.core.utils import ensure_scheme from onegov.form import Form @@ -41,7 +43,7 @@ class MutationForm(Form): ) @property - def proposal_fields(self) -> dict[str, 'CallableProxyType[Field]']: + def proposal_fields(self) -> dict[str, CallableProxyType[Field]]: for fieldset in self.fieldsets: if fieldset.label == 'Proposed changes': return fieldset.fields diff --git a/src/onegov/agency/forms/user_group.py b/src/onegov/agency/forms/user_group.py index 05ae28f808..c515a87aaa 100644 --- a/src/onegov/agency/forms/user_group.py +++ b/src/onegov/agency/forms/user_group.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency import _ from onegov.agency.collections import ExtendedAgencyCollection from onegov.form.fields import ChosenSelectMultipleField @@ -36,7 +38,7 @@ def on_request(self) -> None: for a in ExtendedAgencyCollection(self.request.session).query() ] - def update_model(self, model: 'UserGroup') -> None: + def update_model(self, model: UserGroup) -> None: super().update_model(model) model.role_mappings = [ # type:ignore[assignment] RoleMapping( @@ -51,7 +53,7 @@ def update_model(self, model: 'UserGroup') -> None: model.meta = {} model.meta['immediate_notification'] = self.immediate_notification.data - def apply_model(self, model: 'UserGroup') -> None: + def apply_model(self, model: UserGroup) -> None: super().apply_model(model) mappings = model.role_mappings.all() self.agencies.data = [m.content_id for m in mappings] diff --git a/src/onegov/agency/i18n.py b/src/onegov/agency/i18n.py index 0a174de729..f8345b8c23 100644 --- a/src/onegov/agency/i18n.py +++ b/src/onegov/agency/i18n.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.i18n.translation_string import TranslationStringFactory _ = TranslationStringFactory('onegov.agency') diff --git a/src/onegov/agency/initial_content.py b/src/onegov/agency/initial_content.py index 116c8e7162..ff3bce4731 100644 --- a/src/onegov/agency/initial_content.py +++ b/src/onegov/agency/initial_content.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import module_path from onegov.org.initial_content import load_content, add_pages from onegov.org.models import Organisation @@ -9,7 +11,7 @@ def create_new_organisation( - app: 'AgencyApp', + app: AgencyApp, name: str, locale: str = 'de_CH' ) -> Organisation: diff --git a/src/onegov/agency/layout.py b/src/onegov/agency/layout.py index 91e0cad2e9..08fd4c2f25 100644 --- a/src/onegov/agency/layout.py +++ b/src/onegov/agency/layout.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from itertools import islice from onegov.agency.collections import ExtendedAgencyCollection @@ -112,11 +114,11 @@ class NavTreeMixin: model: Any request: AgencyRequest - def nav_item_url(self, agency: 'ExtendedAgency') -> str: + def nav_item_url(self, agency: ExtendedAgency) -> str: return self.request.link(agency.proxy(), 'as-nav-item') @cached_property - def browsed_agency(self) -> 'ExtendedAgency | None': + def browsed_agency(self) -> ExtendedAgency | None: if ( isinstance(self.model, ExtendedAgencyCollection) and self.model.browse @@ -146,7 +148,7 @@ class AgencyCollectionLayout( NavTreeMixin ): - request: 'AgencyRequest' + request: AgencyRequest @cached_property def breadcrumbs(self) -> list[Link]: @@ -191,7 +193,7 @@ class AgencyLayout( MoveAgencyMixin ): - request: 'AgencyRequest' + request: AgencyRequest def include_editor(self) -> None: self.request.include('redactor') @@ -369,14 +371,14 @@ def move_membership_within_agency_url_template(self) -> str: class AgencyPathMixin: if TYPE_CHECKING: - request: 'AgencyRequest' + request: AgencyRequest def get_ancestors( self, - item: 'ExtendedAgency', + item: ExtendedAgency, with_item: bool = True, - levels: 'Collection[int] | None' = None - ) -> 'Iterator[Link]': + levels: Collection[int] | None = None + ) -> Iterator[Link]: for ix, ancestor in enumerate(item.ancestors, 1): if levels is None or ix in levels: @@ -385,14 +387,14 @@ def get_ancestors( if with_item: yield Link(item.title, self.request.link(item)) - def parent_path(self, agency: 'ExtendedAgency') -> str: + def parent_path(self, agency: ExtendedAgency) -> str: levels = self.request.app.org.agency_display_levels return ' > '.join( ln.text or ln.title for ln in self.get_ancestors(agency, False, levels) ) - def agency_path(self, agency: 'ExtendedAgency') -> str: + def agency_path(self, agency: ExtendedAgency) -> str: return ' > '.join( ln.text or ln.title for ln in self.get_ancestors(agency) @@ -445,7 +447,7 @@ class ExtendedPersonCollectionLayout( AgencyPathMixin ): - request: 'AgencyRequest' + request: AgencyRequest @cached_property def editbar_links(self) -> list[Link | LinkGroup] | None: @@ -476,7 +478,7 @@ def editbar_links(self) -> list[Link | LinkGroup] | None: class ExtendedPersonLayout(PersonLayout, AgencyPathMixin): - request: 'AgencyRequest' + request: AgencyRequest @cached_property def collection(self) -> ExtendedPersonCollection: # type:ignore @@ -501,4 +503,4 @@ def default_membership_title(self) -> str: class AgencySearchLayout(DefaultLayout, AgencyPathMixin): - request: 'AgencyRequest' + request: AgencyRequest diff --git a/src/onegov/agency/models/__init__.py b/src/onegov/agency/models/__init__.py index c972d9ac68..98fcb1d9f9 100644 --- a/src/onegov/agency/models/__init__.py +++ b/src/onegov/agency/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency.models.agency import AgencyPdf from onegov.agency.models.agency import AgencyProxy from onegov.agency.models.agency import ExtendedAgency diff --git a/src/onegov/agency/models/agency.py b/src/onegov/agency/models/agency.py index feea938019..ec0a46e77c 100644 --- a/src/onegov/agency/models/agency.py +++ b/src/onegov/agency/models/agency.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency.models.membership import ExtendedAgencyMembership from onegov.agency.utils import get_html_paragraph_with_line_breaks from onegov.core.crypto import random_token @@ -53,7 +55,7 @@ def es_public(self) -> bool: # type:ignore[override] #: The PDF for the agency and all its suborganizations. pdf = associated(AgencyPdf, 'pdf', 'one-to-one') - role_mappings: 'relationship[list[RoleMapping]]' = relationship( + role_mappings: relationship[list[RoleMapping]] = relationship( RoleMapping, primaryjoin=( "and_(" @@ -71,20 +73,20 @@ def es_public(self) -> bool: # type:ignore[override] if TYPE_CHECKING: # we only allow relating to other ExtendedAgency - parent: relationship['ExtendedAgency | None'] - children: relationship[list['ExtendedAgency']] # type:ignore + parent: relationship[ExtendedAgency | None] + children: relationship[list[ExtendedAgency]] # type:ignore @property - def root(self) -> 'ExtendedAgency': ... + def root(self) -> ExtendedAgency: ... @property - def ancestors(self) -> 'Iterator[ExtendedAgency]': ... + def ancestors(self) -> Iterator[ExtendedAgency]: ... # we only allow ExtendedAgencyMembership memberships memberships: relationship[ # type:ignore[assignment] AppenderQuery[ExtendedAgencyMembership] ] @property - def pdf_file(self) -> 'StoredFile | None': + def pdf_file(self) -> StoredFile | None: """ Returns the PDF content for the agency (and all its suborganizations). @@ -111,25 +113,25 @@ def pdf_file(self, value: IO[bytes] | bytes) -> None: self.pdf = pdf @property - def portrait_html(self) -> 'Markup | None': + def portrait_html(self) -> Markup | None: """ Returns the portrait that is saved as HTML from the redactor js plugin. """ return self.portrait @property - def location_address_html(self) -> 'Markup': + def location_address_html(self) -> Markup: return get_html_paragraph_with_line_breaks(self.location_address) @property - def postal_address_html(self) -> 'Markup': + def postal_address_html(self) -> Markup: return get_html_paragraph_with_line_breaks(self.postal_address) @property - def opening_hours_html(self) -> 'Markup': + def opening_hours_html(self) -> Markup: return get_html_paragraph_with_line_breaks(self.opening_hours) - def proxy(self) -> 'AgencyProxy': + def proxy(self) -> AgencyProxy: """ Returns a proxy object to this agency allowing alternative linking paths. """ @@ -137,7 +139,7 @@ def proxy(self) -> 'AgencyProxy': def add_person( # type:ignore[override] self, - person_id: 'UUID', + person_id: UUID, title: str, *, order_within_agency: int = 2 ** 16, @@ -175,7 +177,7 @@ def add_person( # type:ignore[override] return membership - def deletable(self, request: 'AgencyRequest') -> bool: + def deletable(self, request: AgencyRequest) -> bool: if request.is_admin: return True if self.memberships.first() or self.children: diff --git a/src/onegov/agency/models/membership.py b/src/onegov/agency/models/membership.py index b4b4d66039..3c85703baf 100644 --- a/src/onegov/agency/models/membership.py +++ b/src/onegov/agency/models/membership.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.mixins import dict_property from onegov.core.orm.mixins import meta_property from onegov.org.models.extensions import AccessExtension diff --git a/src/onegov/agency/models/message.py b/src/onegov/agency/models/message.py index 8cd50e6fc0..9c1f1a9e71 100644 --- a/src/onegov/agency/models/message.py +++ b/src/onegov/agency/models/message.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.chat import Message from onegov.org.models.message import TicketMessageMixin @@ -18,10 +20,10 @@ class AgencyMutationMessage(Message, TicketMessageMixin): @classmethod def create( # type:ignore[override] cls, - ticket: 'Ticket', - request: 'AgencyRequest', + ticket: Ticket, + request: AgencyRequest, change: str - ) -> 'Self': + ) -> Self: return super().create(ticket, request, change=change) @@ -34,8 +36,8 @@ class PersonMutationMessage(Message, TicketMessageMixin): @classmethod def create( # type:ignore[override] cls, - ticket: 'Ticket', - request: 'AgencyRequest', + ticket: Ticket, + request: AgencyRequest, change: str - ) -> 'Self': + ) -> Self: return super().create(ticket, request, change=change) diff --git a/src/onegov/agency/models/move.py b/src/onegov/agency/models/move.py index a14fed7cf1..788010d435 100644 --- a/src/onegov/agency/models/move.py +++ b/src/onegov/agency/models/move.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.people import AgencyMembershipCollection @@ -30,10 +32,10 @@ class Move(Generic[_M, _IdT_contra]): def __init__( self, - session: 'Session', + session: Session, subject_id: _IdT_contra, target_id: _IdT_contra, - direction: 'MoveDirection' + direction: MoveDirection ) -> None: self.session = session self.subject_id = subject_id @@ -41,7 +43,7 @@ def __init__( self.direction = direction @cached_property - def collection(self) -> 'SupportsById[_M, _IdT_contra]': + def collection(self) -> SupportsById[_M, _IdT_contra]: raise NotImplementedError @cached_property @@ -60,7 +62,7 @@ class AgencyMove(Move['ExtendedAgency', int]): """ Represents a single move of a suborganization. """ @cached_property - def collection(self) -> 'ExtendedAgencyCollection': + def collection(self) -> ExtendedAgencyCollection: from onegov.agency.collections import ExtendedAgencyCollection return ExtendedAgencyCollection(self.session) diff --git a/src/onegov/agency/models/mutation.py b/src/onegov/agency/models/mutation.py index 60c89f2136..d5a703b773 100644 --- a/src/onegov/agency/models/mutation.py +++ b/src/onegov/agency/models/mutation.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.agency import _ from onegov.ticket import TicketCollection @@ -43,16 +45,16 @@ class Mutation(Generic[_M, _IdT_contra]): def __init__( self, - session: 'Session', + session: Session, target_id: _IdT_contra, - ticket_id: 'UUID' + ticket_id: UUID ) -> None: self.session = session self.target_id = target_id self.ticket_id = ticket_id @cached_property - def collection(self) -> 'SupportsById[_M, _IdT_contra]': + def collection(self) -> SupportsById[_M, _IdT_contra]: raise NotImplementedError @cached_property @@ -60,7 +62,7 @@ def target(self) -> _M | None: return self.collection.by_id(self.target_id) @cached_property - def ticket(self) -> 'Ticket | None': + def ticket(self) -> Ticket | None: return TicketCollection(self.session).by_id(self.ticket_id) @cached_property @@ -75,7 +77,7 @@ def changes(self) -> dict[str, Any]: def labels(self) -> dict[str, str]: return {} - def apply(self, items: 'Iterable[str]') -> None: + def apply(self, items: Iterable[str]) -> None: assert self.ticket is not None self.ticket.handler_data['state'] = 'applied' for item in items: @@ -87,7 +89,7 @@ def apply(self, items: 'Iterable[str]') -> None: class AgencyMutation(Mutation['ExtendedAgency', int]): @cached_property - def collection(self) -> 'ExtendedAgencyCollection': + def collection(self) -> ExtendedAgencyCollection: from onegov.agency.collections import ExtendedAgencyCollection return ExtendedAgencyCollection(self.session) @@ -110,7 +112,7 @@ def labels(self) -> dict[str, str]: class PersonMutation(Mutation['ExtendedPerson', 'UUID']): @cached_property - def collection(self) -> 'ExtendedPersonCollection': + def collection(self) -> ExtendedPersonCollection: from onegov.agency.collections import ExtendedPersonCollection return ExtendedPersonCollection(self.session) diff --git a/src/onegov/agency/models/person.py b/src/onegov/agency/models/person.py index e632d8c3c8..c72cfdabda 100644 --- a/src/onegov/agency/models/person.py +++ b/src/onegov/agency/models/person.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency.utils import get_html_paragraph_with_line_breaks from onegov.org.models import Organisation from onegov.org.models.extensions import AccessExtension @@ -70,18 +72,18 @@ def phone_es(self) -> list[str]: return [r for r in result if r] @property - def location_address_html(self) -> 'Markup': + def location_address_html(self) -> Markup: return get_html_paragraph_with_line_breaks(self.location_address) @property - def postal_address_html(self) -> 'Markup': + def postal_address_html(self) -> Markup: return get_html_paragraph_with_line_breaks(self.postal_address) @property - def notes_html(self) -> 'Markup': + def notes_html(self) -> Markup: return get_html_paragraph_with_line_breaks(self.notes) - def deletable(self, request: 'AgencyRequest') -> bool: + def deletable(self, request: AgencyRequest) -> bool: if request.is_admin: return True if self.memberships.first(): diff --git a/src/onegov/agency/models/ticket.py b/src/onegov/agency/models/ticket.py index c085d3ec7e..9c86e4748b 100644 --- a/src/onegov/agency/models/ticket.py +++ b/src/onegov/agency/models/ticket.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from markupsafe import Markup from onegov.agency.collections import ExtendedAgencyCollection @@ -31,9 +33,9 @@ class AgencyMutationTicket(OrgTicketMixin, Ticket): if TYPE_CHECKING: @property - def handler(self) -> 'AgencyMutationHandler': ... + def handler(self) -> AgencyMutationHandler: ... - def reference_group(self, request: 'OrgRequest') -> str: + def reference_group(self, request: OrgRequest) -> str: return self.title @@ -43,9 +45,9 @@ class PersonMutationTicket(OrgTicketMixin, Ticket): if TYPE_CHECKING: @property - def handler(self) -> 'PersonMutationHandler': ... + def handler(self) -> PersonMutationHandler: ... - def reference_group(self, request: 'OrgRequest') -> str: + def reference_group(self, request: OrgRequest) -> str: return self.title @@ -60,7 +62,7 @@ def collection(self) -> ExtendedAgencyCollection: return ExtendedAgencyCollection(self.session) @cached_property - def agency(self) -> 'ExtendedAgency | None': + def agency(self) -> ExtendedAgency | None: return self.collection.by_id(self.data['handler_data']['id']) @cached_property @@ -109,7 +111,7 @@ def group(self) -> str: def get_summary( self, - request: 'AgencyRequest' # type:ignore[override] + request: AgencyRequest # type:ignore[override] ) -> Markup: layout = AgencyLayout(self.agency, request) @@ -125,7 +127,7 @@ def get_summary( } ) - def get_links(self, request: 'AgencyRequest') -> list[Link]: # type:ignore + def get_links(self, request: AgencyRequest) -> list[Link]: # type:ignore if self.deleted: return [] @@ -166,7 +168,7 @@ def collection(self) -> ExtendedPersonCollection: return ExtendedPersonCollection(self.session) @cached_property - def person(self) -> 'ExtendedPerson | None': + def person(self) -> ExtendedPerson | None: return self.collection.by_id(self.data['handler_data']['id']) @cached_property @@ -215,7 +217,7 @@ def group(self) -> str: def get_summary( self, - request: 'AgencyRequest' # type:ignore[override] + request: AgencyRequest # type:ignore[override] ) -> Markup: layout = ExtendedPersonLayout(self.person, request) @@ -231,7 +233,7 @@ def get_summary( } ) - def get_links(self, request: 'AgencyRequest') -> list[Link]: # type:ignore + def get_links(self, request: AgencyRequest) -> list[Link]: # type:ignore if self.deleted: return [] diff --git a/src/onegov/agency/path.py b/src/onegov/agency/path.py index 9ef6025b56..df6cf4985c 100644 --- a/src/onegov/agency/path.py +++ b/src/onegov/agency/path.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency.app import AgencyApp from onegov.agency.collections import ExtendedAgencyCollection from onegov.agency.collections import ExtendedPersonCollection @@ -52,7 +54,7 @@ def get_agencies( path='/organization', absorb=True ) -def get_agency(app: AgencyApp, absorb: str) -> 'ExtendedAgency | None': +def get_agency(app: AgencyApp, absorb: str) -> ExtendedAgency | None: collection = ExtendedAgencyCollection(app.session()) return collection.by_path(absorb) @@ -62,7 +64,7 @@ def get_agency(app: AgencyApp, absorb: str) -> 'ExtendedAgency | None': path='/agency/{id}', converters={'id': int} ) -def get_agency_proxy(app: AgencyApp, id: int) -> 'ExtendedAgency | None': +def get_agency_proxy(app: AgencyApp, id: int) -> ExtendedAgency | None: return ExtendedAgencyCollection(app.session()).by_id(id) diff --git a/src/onegov/agency/pdf.py b/src/onegov/agency/pdf.py index 4b490789f3..07d7749a48 100644 --- a/src/onegov/agency/pdf.py +++ b/src/onegov/agency/pdf.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from io import BytesIO @@ -30,20 +32,20 @@ class AgencyPdfDefault(Pdf): previous_level_context: int | None = None @property - def page_fn(self) -> 'Callable[[Canvas, Template], None]': + def page_fn(self) -> Callable[[Canvas, Template], None]: return page_fn_footer @property - def page_fn_later(self) -> 'Callable[[Canvas, Template], None]': + def page_fn_later(self) -> Callable[[Canvas, Template], None]: return page_fn_header_and_footer @classmethod def from_agencies( cls, - agencies: 'Iterable[ExtendedAgency]', + agencies: Iterable[ExtendedAgency], title: str, toc: bool, - exclude: 'Collection[str]', + exclude: Collection[str], page_break_on_level: int = 1, link_color: str | None = None, underline_links: bool = False @@ -82,8 +84,8 @@ def from_agencies( def memberships( self, - agency: 'ExtendedAgency', - exclude: 'Collection[str]' + agency: ExtendedAgency, + exclude: Collection[str] ) -> None: """ Adds the memberships of an agency as table. """ @@ -131,8 +133,8 @@ def memberships( def agency( self, - agency: 'ExtendedAgency', - exclude: 'Collection[str]', + agency: ExtendedAgency, + exclude: Collection[str], level: int = 1, content_so_far: bool = False, skip_title: bool = False, @@ -199,7 +201,7 @@ class AgencyPdfZg(AgencyPdfDefault): """ A PDF with the CI of the canton of ZG. """ @staticmethod - def page_fn_footer(canvas: 'Canvas', doc: 'Template') -> None: + def page_fn_footer(canvas: Canvas, doc: Template) -> None: """ A footer with the title and print date on the left and the page numbers on the right. @@ -222,16 +224,16 @@ def page_fn_footer(canvas: 'Canvas', doc: 'Template') -> None: canvas.drawRightString( doc.pagesize[0] - doc.rightMargin, doc.bottomMargin / 2, - f'{canvas.getPageNumber()}' + f'{canvas.getPageNumber()}' # type:ignore[no-untyped-call] ) canvas.restoreState() @property - def page_fn(self) -> 'Callable[[Canvas, Template], None]': + def page_fn(self) -> Callable[[Canvas, Template], None]: return page_fn_header_logo @property - def page_fn_later(self) -> 'Callable[[Canvas, Template], None]': + def page_fn_later(self) -> Callable[[Canvas, Template], None]: return self.page_fn_footer def __init__(self, *args: Any, **kwargs: Any) -> None: @@ -250,7 +252,7 @@ class AgencyPdfAr(AgencyPdfDefault): """ A PDF with the CI of the canton of AR. """ @staticmethod - def page_fn_footer(canvas: 'Canvas', doc: 'Template') -> None: + def page_fn_footer(canvas: Canvas, doc: Template) -> None: """ A footer with the print date on the left and the page numbers on the right. @@ -267,14 +269,14 @@ def page_fn_footer(canvas: 'Canvas', doc: 'Template') -> None: canvas.drawRightString( doc.pagesize[0] - doc.rightMargin, doc.bottomMargin / 2, - f'{canvas.getPageNumber()}' + f'{canvas.getPageNumber()}' # type:ignore[no-untyped-call] ) canvas.restoreState() @staticmethod def page_fn_header_logo_and_footer( - canvas: 'Canvas', - doc: 'Template' + canvas: Canvas, + doc: Template ) -> None: """ A header with the logo, a footer with the print date and page numbers. @@ -296,7 +298,7 @@ def page_fn_header_logo_and_footer( AgencyPdfAr.page_fn_footer(canvas, doc) @staticmethod - def page_fn_header_and_footer(canvas: 'Canvas', doc: 'Template') -> None: + def page_fn_header_and_footer(canvas: Canvas, doc: Template) -> None: """ A header with the title and author, a footer with the print date and page numbers. @@ -314,11 +316,11 @@ def page_fn_header_and_footer(canvas: 'Canvas', doc: 'Template') -> None: AgencyPdfAr.page_fn_footer(canvas, doc) @property - def page_fn(self) -> 'Callable[[Canvas, Template], None]': + def page_fn(self) -> Callable[[Canvas, Template], None]: return self.page_fn_header_logo_and_footer @property - def page_fn_later(self) -> 'Callable[[Canvas, Template], None]': + def page_fn_later(self) -> Callable[[Canvas, Template], None]: return self.page_fn_header_and_footer def __init__(self, *args: Any, **kwargs: Any) -> None: @@ -356,7 +358,7 @@ class AgencyPdfBs(AgencyPdfDefault): font_size = 11 @staticmethod - def page_fn_header(canvas: 'Canvas', doc: 'Template') -> None: + def page_fn_header(canvas: Canvas, doc: Template) -> None: """ A header with the logo, a footer with the print date and page numbers. @@ -378,7 +380,7 @@ def page_fn_header(canvas: 'Canvas', doc: 'Template') -> None: AgencyPdfBs.page_fn_footer(canvas, doc) @staticmethod - def page_fn_footer(canvas: 'Canvas', doc: 'Template') -> None: + def page_fn_footer(canvas: Canvas, doc: Template) -> None: assert hasattr(doc, 'created') canvas.saveState() canvas.setFont('Helvetica', 9) @@ -390,12 +392,12 @@ def page_fn_footer(canvas: 'Canvas', doc: 'Template') -> None: canvas.drawRightString( doc.pagesize[0] - doc.rightMargin, doc.bottomMargin / 2, - f'{canvas.getPageNumber()}' + f'{canvas.getPageNumber()}' # type:ignore[no-untyped-call] ) canvas.restoreState() @property - def page_fn(self) -> 'Callable[[Canvas, Template], None]': + def page_fn(self) -> Callable[[Canvas, Template], None]: return self.page_fn_header def __init__(self, *args: Any, **kwargs: Any) -> None: @@ -422,8 +424,8 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: def init_a4_portrait( self, - page_fn: '_PageCallback' = empty_page_fn, - page_fn_later: '_PageCallback | None ' = None, + page_fn: _PageCallback = empty_page_fn, + page_fn_later: _PageCallback | None = None, **_ignored: object ) -> None: super().init_a4_portrait( diff --git a/src/onegov/agency/request.py b/src/onegov/agency/request.py index faeace7d58..dd73048a27 100644 --- a/src/onegov/agency/request.py +++ b/src/onegov/agency/request.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.org.request import OrgRequest @@ -9,7 +11,7 @@ class AgencyRequest(OrgRequest): - app: 'AgencyApp' + app: AgencyApp @cached_property def current_role(self) -> str | None: diff --git a/src/onegov/agency/security.py b/src/onegov/agency/security.py index 16ca3b95c7..d1d20ed487 100644 --- a/src/onegov/agency/security.py +++ b/src/onegov/agency/security.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency import AgencyApp from onegov.agency.collections import ExtendedAgencyCollection from onegov.agency.models import AgencyMembershipMoveWithinAgency @@ -21,8 +23,8 @@ def get_current_role( - session: 'Session', - identity: 'Identity | NoIdentity' + session: Session, + identity: Identity | NoIdentity ) -> str | None: """ Returns the current role of the identity. Elevates the role from member to editor if any group role mapping with editor role is present. @@ -45,7 +47,7 @@ def get_current_role( def has_permission( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: object, permission: object ) -> bool: @@ -62,7 +64,7 @@ def has_permission( def has_model_permission( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: object, permission: object ) -> bool: @@ -94,7 +96,7 @@ def has_model_permission( @AgencyApp.permission_rule(model=object, permission=object) def has_permission_all( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: object, permission: object ) -> bool: @@ -106,7 +108,7 @@ def has_permission_all( @AgencyApp.permission_rule(model=Agency, permission=object) def has_permission_agency( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: Agency, permission: object ) -> bool: @@ -116,7 +118,7 @@ def has_permission_agency( @AgencyApp.permission_rule(model=AgencyMembership, permission=object) def has_permission_agency_membership( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: AgencyMembership, permission: object ) -> bool: @@ -132,7 +134,7 @@ def has_permission_agency_membership( @AgencyApp.permission_rule(model=Person, permission=object) def has_permission_person( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: Person, permission: object ) -> bool: @@ -155,7 +157,7 @@ def has_permission_person( @AgencyApp.permission_rule(model=AgencyCollection, permission=object) def has_permission_agency_collection( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: AgencyCollection, permission: object ) -> bool: @@ -165,7 +167,7 @@ def has_permission_agency_collection( @AgencyApp.permission_rule(model=AgencyMove, permission=object) def has_permission_agency_move( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: AgencyMove, permission: object ) -> bool: @@ -186,7 +188,7 @@ def has_permission_agency_move( ) def has_permission_agency_membership_move_within_agency( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: AgencyMembershipMoveWithinAgency, permission: object ) -> bool: @@ -207,7 +209,7 @@ def has_permission_agency_membership_move_within_agency( ) def has_permission_agency_membership_move_within_person( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: AgencyMembershipMoveWithinPerson, permission: object ) -> bool: @@ -226,7 +228,7 @@ def has_permission_agency_membership_move_within_person( @AgencyApp.permission_rule(model=AgencyMutationTicket, permission=object) def has_permission_agency_mutation_ticket( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: AgencyMutationTicket, permission: object ) -> bool: @@ -240,7 +242,7 @@ def has_permission_agency_mutation_ticket( @AgencyApp.permission_rule(model=PersonMutationTicket, permission=object) def has_permission_person_mutation_ticket( app: AgencyApp, - identity: 'Identity', + identity: Identity, model: PersonMutationTicket, permission: object ) -> bool: diff --git a/src/onegov/agency/theme/__init__.py b/src/onegov/agency/theme/__init__.py index 4a056270b0..cb5c3d49ba 100644 --- a/src/onegov/agency/theme/__init__.py +++ b/src/onegov/agency/theme/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency.theme.agency_theme import AgencyTheme __all__ = ( diff --git a/src/onegov/agency/theme/agency_theme.py b/src/onegov/agency/theme/agency_theme.py index 1d2ac1c6ab..9e0606a742 100644 --- a/src/onegov/agency/theme/agency_theme.py +++ b/src/onegov/agency/theme/agency_theme.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import module_path from onegov.org.theme import OrgTheme diff --git a/src/onegov/agency/upgrade.py b/src/onegov/agency/upgrade.py index fe19607c46..9658963467 100644 --- a/src/onegov/agency/upgrade.py +++ b/src/onegov/agency/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + from markupsafe import Markup from onegov.core.upgrade import upgrade_task from onegov.core.upgrade import UpgradeContext diff --git a/src/onegov/agency/utils.py b/src/onegov/agency/utils.py index f9cbd0711e..bfe18aa110 100644 --- a/src/onegov/agency/utils.py +++ b/src/onegov/agency/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import operator from email.headerregistry import Address from markupsafe import Markup @@ -28,8 +30,8 @@ def handle_empty_p_tags(html: Markup) -> Markup: def emails_for_new_ticket( model: Agency | Person, - request: 'AgencyRequest' -) -> 'Iterator[Address]': + request: AgencyRequest +) -> Iterator[Address]: """ Returns an iterator with all the unique email addresses that need to be notified for a new ticket of this type @@ -103,7 +105,7 @@ def emails_for_new_ticket( def ticket_groups( agency: Agency, groupids: list[str] | None -) -> list['UserGroup']: +) -> list[UserGroup]: return [ group for role_mapping in getattr(agency, 'role_mappings', ()) @@ -122,13 +124,13 @@ def get_html_paragraph_with_line_breaks(text: str | None) -> Markup: def filter_modified_or_created( - query: 'Query[_T]', + query: Query[_T], relate: Literal['>', '<', '>=', '<=', '=='], # FIXME: This is a bit lax about types, SQLAlchemy is doing the heavy # lifting here, auto casting ISO formatted date strings - comparison_property: 'datetime | str', - collection_class: type['TimestampMixin'] -) -> 'Query[_T]': + comparison_property: datetime | str, + collection_class: type[TimestampMixin] +) -> Query[_T]: ops = { '>': operator.gt, diff --git a/src/onegov/agency/views/agencies.py b/src/onegov/agency/views/agencies.py index 92cbddd40f..bc4f80355a 100644 --- a/src/onegov/agency/views/agencies.py +++ b/src/onegov/agency/views/agencies.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import datetime from datetime import timedelta from morepath import redirect @@ -37,7 +39,7 @@ def get_agency_form_class( model: object, - request: 'AgencyRequest' + request: AgencyRequest ) -> type[ExtendedAgencyForm]: if isinstance(model, ExtendedAgency): @@ -49,7 +51,7 @@ def get_agency_form_class( def get_membership_form_class( model: object, - request: 'AgencyRequest' + request: AgencyRequest ) -> type[MembershipForm]: if isinstance(model, ExtendedAgencyMembership): @@ -66,8 +68,8 @@ def get_membership_form_class( ) def view_agencies( self: ExtendedAgencyCollection, - request: 'AgencyRequest' -) -> 'RenderData': + request: AgencyRequest +) -> RenderData: pdf_link = None root_pdf_modified = request.app.root_pdf_modified @@ -92,8 +94,8 @@ def view_agencies( ) def view_agencies_sort( self: ExtendedAgencyCollection, - request: 'AgencyRequest' -) -> 'RenderData': + request: AgencyRequest +) -> RenderData: layout = AgencyCollectionLayout(self, request) @@ -117,8 +119,8 @@ def view_agencies_sort( ) def view_agency( self: ExtendedAgency, - request: 'AgencyRequest' -) -> 'RenderData': + request: AgencyRequest +) -> RenderData: return { 'title': self.title, @@ -136,8 +138,8 @@ def view_agency( ) def view_agency_sort( self: ExtendedAgency, - request: 'AgencyRequest' -) -> 'RenderData': + request: AgencyRequest +) -> RenderData: layout = AgencyLayout(self, request) return { @@ -171,12 +173,12 @@ def view_agency_sort( ) def view_agency_as_nav_item( self: ExtendedAgency, - request: 'AgencyRequest' + request: AgencyRequest ) -> str: layout = AgencyCollectionLayout(self, request) @request.after - def push_history_state(response: 'BaseResponse') -> None: + def push_history_state(response: BaseResponse) -> None: response.headers.add( 'X-IC-PushURL', request.class_link( @@ -202,9 +204,9 @@ def push_history_state(response: 'BaseResponse') -> None: ) def add_root_agency( self: ExtendedAgencyCollection, - request: 'AgencyRequest', + request: AgencyRequest, form: ExtendedAgencyForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: if form.submitted(request): agency = self.add_root(**form.get_useful_data()) @@ -231,9 +233,9 @@ def add_root_agency( ) def add_agency( self: ExtendedAgency, - request: 'AgencyRequest', + request: AgencyRequest, form: ExtendedAgencyForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: if form.submitted(request): collection = ExtendedAgencyCollection(request.session) @@ -261,9 +263,9 @@ def add_agency( ) def add_membership( self: ExtendedAgency, - request: 'AgencyRequest', + request: AgencyRequest, form: MembershipForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: if form.submitted(request): self.add_person(**form.get_useful_data()) @@ -287,7 +289,7 @@ def add_membership( request_method='POST', permission=Private, ) -def sort_relationships(self: ExtendedAgency, request: 'AgencyRequest') -> None: +def sort_relationships(self: ExtendedAgency, request: AgencyRequest) -> None: request.assert_valid_csrf_token() self.sort_relationships() @@ -298,7 +300,7 @@ def sort_relationships(self: ExtendedAgency, request: 'AgencyRequest') -> None: request_method='POST', permission=Private, ) -def sort_children(self: ExtendedAgency, request: 'AgencyRequest') -> None: +def sort_children(self: ExtendedAgency, request: AgencyRequest) -> None: request.assert_valid_csrf_token() self.sort_children() @@ -312,9 +314,9 @@ def sort_children(self: ExtendedAgency, request: 'AgencyRequest') -> None: ) def edit_agency( self: ExtendedAgency, - request: 'AgencyRequest', + request: AgencyRequest, form: ExtendedAgencyForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: if form.submitted(request): form.update_model(self) @@ -348,9 +350,9 @@ def edit_agency( ) def change_agency_url( self: ExtendedAgency, - request: 'AgencyRequest', + request: AgencyRequest, form: ChangeAdjacencyListUrlForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: layout = AgencyLayout(self, request) layout.breadcrumbs.append(Link(_('Change URL'), '#')) @@ -386,9 +388,9 @@ def change_agency_url( ) def move_agency( self: ExtendedAgency, - request: 'AgencyRequest', + request: AgencyRequest, form: MoveAgencyForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: if form.submitted(request): form.update_model(self) @@ -418,7 +420,7 @@ def move_agency( ) def get_root_pdf( self: ExtendedAgencyCollection, - request: 'AgencyRequest' + request: AgencyRequest ) -> Response: last_modified = request.app.root_pdf_modified @@ -426,7 +428,7 @@ def get_root_pdf( return Response(status='503 Service Unavailable') @request.after - def cache_headers(response: 'BaseResponse') -> None: + def cache_headers(response: BaseResponse) -> None: max_age = 1 * 24 * 60 * 60 expires = datetime.now() + timedelta(seconds=max_age) fmt = '%a, %d %b %Y %H:%M:%S GMT' @@ -454,9 +456,9 @@ def cache_headers(response: 'BaseResponse') -> None: ) def create_root_pdf( self: ExtendedAgencyCollection, - request: 'AgencyRequest', + request: AgencyRequest, form: Form -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: org = request.app.org page_break_level = int(org.meta.get( @@ -499,9 +501,9 @@ def create_root_pdf( ) def create_agency_pdf( self: ExtendedAgency, - request: 'AgencyRequest', + request: AgencyRequest, form: Form -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: org = request.app.org page_break_level = int(org.meta.get( @@ -539,7 +541,7 @@ def create_agency_pdf( request_method='DELETE', permission=Private ) -def delete_agency(self: ExtendedAgency, request: 'AgencyRequest') -> None: +def delete_agency(self: ExtendedAgency, request: AgencyRequest) -> None: if not self.deletable(request): request.alert( _("Agency with memberships or suborganizations can't be deleted") @@ -554,7 +556,7 @@ def delete_agency(self: ExtendedAgency, request: 'AgencyRequest') -> None: permission=Private, request_method='PUT' ) -def execute_agency_move(self: AgencyMove, request: 'AgencyRequest') -> None: +def execute_agency_move(self: AgencyMove, request: AgencyRequest) -> None: request.assert_valid_csrf_token() self.execute() @@ -568,9 +570,9 @@ def execute_agency_move(self: AgencyMove, request: 'AgencyRequest') -> None: ) def report_agency_change( self: ExtendedAgency, - request: 'AgencyRequest', + request: AgencyRequest, form: AgencyMutationForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: if form.submitted(request): assert form.submitter_email.data is not None diff --git a/src/onegov/agency/views/memberships.py b/src/onegov/agency/views/memberships.py index 44a80d70a1..cbc1867550 100644 --- a/src/onegov/agency/views/memberships.py +++ b/src/onegov/agency/views/memberships.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from morepath.request import Response from onegov.agency import _ @@ -23,7 +25,7 @@ def get_membership_form_class( model: ExtendedAgencyMembership, - request: 'AgencyRequest' + request: AgencyRequest ) -> type[MembershipForm]: return model.with_content_extensions(MembershipForm, request) @@ -35,8 +37,8 @@ def get_membership_form_class( ) def view_membership( self: AgencyMembership, - request: 'AgencyRequest' -) -> 'RenderData': + request: AgencyRequest +) -> RenderData: return { 'title': self.title, @@ -54,9 +56,9 @@ def view_membership( ) def edit_membership( self: ExtendedAgencyMembership, - request: 'AgencyRequest', + request: AgencyRequest, form: MembershipForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: if form.submitted(request): form.populate_obj(self) @@ -83,7 +85,7 @@ def edit_membership( ) def delete_membership( self: AgencyMembership, - request: 'AgencyRequest' + request: AgencyRequest ) -> None: request.assert_valid_csrf_token() @@ -97,7 +99,7 @@ def delete_membership( ) def move_membership_within_agency( self: AgencyMembershipMoveWithinAgency, - request: 'AgencyRequest' + request: AgencyRequest ) -> None: request.assert_valid_csrf_token() self.execute() @@ -110,7 +112,7 @@ def move_membership_within_agency( ) def move_membership_within_person( self: AgencyMembershipMoveWithinPerson, - request: 'AgencyRequest' + request: AgencyRequest ) -> None: request.assert_valid_csrf_token() self.execute() @@ -123,7 +125,7 @@ def move_membership_within_person( ) def vcard_export_membership( self: AgencyMembership, - request: 'AgencyRequest' + request: AgencyRequest ) -> Response: """ Returns the memberships vCard. """ diff --git a/src/onegov/agency/views/mutations.py b/src/onegov/agency/views/mutations.py index 5d655ddb79..b789439975 100644 --- a/src/onegov/agency/views/mutations.py +++ b/src/onegov/agency/views/mutations.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.agency import _ from onegov.agency import AgencyApp @@ -28,9 +30,9 @@ ) def apply_agency_mutation( self: AgencyMutation, - request: 'AgencyRequest', + request: AgencyRequest, form: ApplyMutationForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): form.update_model() @@ -62,9 +64,9 @@ def apply_agency_mutation( ) def apply_person_mutation( self: PersonMutation, - request: 'AgencyRequest', + request: AgencyRequest, form: ApplyMutationForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): form.update_model() diff --git a/src/onegov/agency/views/organisation.py b/src/onegov/agency/views/organisation.py index 85b25c7bc6..b94300c93d 100644 --- a/src/onegov/agency/views/organisation.py +++ b/src/onegov/agency/views/organisation.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency import _ from onegov.agency import AgencyApp from onegov.agency.collections import ExtendedAgencyCollection @@ -27,8 +29,8 @@ ) def view_hidden_agencies( self: Organisation, - request: 'AgencyRequest' -) -> 'RenderData': + request: AgencyRequest +) -> RenderData: session = request.session diff --git a/src/onegov/agency/views/page.py b/src/onegov/agency/views/page.py index 2f34d8f1a7..74b4f28a78 100644 --- a/src/onegov/agency/views/page.py +++ b/src/onegov/agency/views/page.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency import AgencyApp from onegov.agency.layout import PageLayout from onegov.core.security import Public @@ -15,7 +17,7 @@ @AgencyApp.html(model=Topic, template='topic.pt', permission=Public) def view_topic( self: Topic, - request: 'AgencyRequest' -) -> 'RenderData | Response': + request: AgencyRequest +) -> RenderData | Response: layout = PageLayout(self, request) return view_topic_base(self, request, layout) diff --git a/src/onegov/agency/views/people.py b/src/onegov/agency/views/people.py index 6ff99b1b77..0a509b3fe2 100644 --- a/src/onegov/agency/views/people.py +++ b/src/onegov/agency/views/people.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from datetime import datetime, timedelta from itertools import groupby @@ -44,7 +46,7 @@ class FilterOption(NamedTuple): def get_person_form_class( model: object, - request: 'AgencyRequest' + request: AgencyRequest ) -> type[PersonForm]: if isinstance(model, ExtendedPerson): @@ -59,8 +61,8 @@ def get_person_form_class( ) def view_people( self: ExtendedPersonCollection, - request: 'AgencyRequest' -) -> 'RenderData': + request: AgencyRequest +) -> RenderData: request.include('common') request.include('chosen') @@ -140,9 +142,9 @@ def get_items_by_letter(self) -> dict[str, tuple[ExtendedPerson, ...]]: ) def create_people_xlsx( self: ExtendedPersonCollection, - request: 'AgencyRequest', + request: AgencyRequest, form: Form -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: if form.submitted(request): request.app.people_xlsx = export_person_xlsx( @@ -175,14 +177,14 @@ def create_people_xlsx( ) def get_people_xlsx( self: ExtendedPersonCollection, - request: 'AgencyRequest' + request: AgencyRequest ) -> Response: if not request.app.people_xlsx_exists: return Response(status='503 Service Unavailable') @request.after - def cache_headers(response: 'BaseResponse') -> None: + def cache_headers(response: BaseResponse) -> None: last_modified = request.app.people_xlsx_modified if last_modified: max_age = 1 * 24 * 60 * 60 @@ -210,8 +212,8 @@ def cache_headers(response: 'BaseResponse') -> None: ) def view_person( self: ExtendedPerson, - request: 'AgencyRequest' -) -> 'RenderData': + request: AgencyRequest +) -> RenderData: return { 'title': self.title, @@ -228,8 +230,8 @@ def view_person( ) def view_sort_person( self: ExtendedPerson, - request: 'AgencyRequest' -) -> 'RenderData': + request: AgencyRequest +) -> RenderData: layout = ExtendedPersonLayout(self, request) @@ -261,9 +263,9 @@ def view_sort_person( ) def add_person( self: ExtendedPersonCollection, - request: 'AgencyRequest', + request: AgencyRequest, form: PersonForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: if form.submitted(request): person = self.add(**form.get_useful_data()) @@ -292,9 +294,9 @@ def add_person( ) def edit_person( self: ExtendedPerson, - request: 'AgencyRequest', + request: AgencyRequest, form: PersonForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: if form.submitted(request): form.populate_obj(self) @@ -323,7 +325,7 @@ def edit_person( permission=Private) def handle_delete_person( self: ExtendedPerson, - request: 'AgencyRequest' + request: AgencyRequest ) -> None: if not self.deletable(request): @@ -334,9 +336,9 @@ def handle_delete_person( def do_report_person_change( self: ExtendedPerson, - request: 'AgencyRequest', + request: AgencyRequest, form: PersonMutationForm -) -> 'Ticket': +) -> Ticket: session = request.session with session.no_autoflush: @@ -395,9 +397,9 @@ def do_report_person_change( ) def report_person_change( self: ExtendedPerson, - request: 'AgencyRequest', + request: AgencyRequest, form: PersonMutationForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: if form.submitted(request): ticket = do_report_person_change(self, request, form) diff --git a/src/onegov/agency/views/search.py b/src/onegov/agency/views/search.py index dfdf8a9a61..12cc92d83c 100644 --- a/src/onegov/agency/views/search.py +++ b/src/onegov/agency/views/search.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency import AgencyApp from onegov.agency.layout import AgencySearchLayout from onegov.core.security import Public @@ -15,9 +17,9 @@ @AgencyApp.html(model=Search, template='search.pt', permission=Public) def search( - self: Search['Base'], - request: 'AgencyRequest' -) -> 'RenderData | Response': + self: Search[Base], + request: AgencyRequest +) -> RenderData | Response: data = search_view(self, request) if isinstance(data, dict): diff --git a/src/onegov/agency/views/settings.py b/src/onegov/agency/views/settings.py index 9f226e40b0..64a43d482f 100644 --- a/src/onegov/agency/views/settings.py +++ b/src/onegov/agency/views/settings.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.agency import _ from onegov.agency.app import AgencyApp from onegov.core.security import Secret @@ -142,8 +144,8 @@ def process_obj(self, obj: Organisation) -> None: # type:ignore def populate_obj( # type: ignore[override] self, obj: Organisation, # type: ignore[override] - exclude: 'Collection[str] | None' = None, - include: 'Collection[str] | None' = None + exclude: Collection[str] | None = None, + include: Collection[str] | None = None ) -> None: super().populate_obj(obj, exclude, include) @@ -175,7 +177,7 @@ def populate_obj( # type: ignore[override] ) def handle_agency_settings( self: Organisation, - request: 'AgencyRequest', + request: AgencyRequest, form: AgencySettingsForm -) -> 'RenderData | Response': +) -> RenderData | Response: return handle_generic_settings(self, request, form, _('Agencies')) diff --git a/src/onegov/api/__init__.py b/src/onegov/api/__init__.py index 02f802e817..e80fec1e72 100644 --- a/src/onegov/api/__init__.py +++ b/src/onegov/api/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.api.integration import ApiApp from onegov.api.models import ApiEndpoint, ApiInvalidParamException from onegov.api.models import log diff --git a/src/onegov/api/integration.py b/src/onegov/api/integration.py index cb71c2eaa8..dd58446837 100644 --- a/src/onegov/api/integration.py +++ b/src/onegov/api/integration.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import App @@ -35,7 +37,7 @@ def configure_api(self, **cfg: Any) -> None: ) @property - def rate_limit_cache(self) -> 'cache.RedisCacheRegion': + def rate_limit_cache(self) -> cache.RedisCacheRegion: """ A cache for rate limits. """ _limit, expiration = self.rate_limit diff --git a/src/onegov/api/models.py b/src/onegov/api/models.py index 7408584a63..70950dd947 100644 --- a/src/onegov/api/models.py +++ b/src/onegov/api/models.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from json import JSONDecodeError from logging import getLogger @@ -51,7 +53,7 @@ def cached_subset(self) -> Query[_M]: ... def page(self) -> int | None: ... @property def page_index(self) -> int: ... - def page_by_index(self, index: int) -> 'Self': ... + def page_by_index(self, index: int) -> Self: ... @property def subset_count(self) -> int: ... @property @@ -61,11 +63,11 @@ def offset(self) -> int: ... @property def pages_count(self) -> int: ... @property - def pages(self) -> 'Iterator[Self]': ... + def pages(self) -> Iterator[Self]: ... @property - def previous(self) -> 'Self | None': ... + def previous(self) -> Self | None: ... @property - def next(self) -> 'Self | None': ... + def next(self) -> Self | None: ... log = getLogger('onegov.api') log.addHandler(NullHandler()) @@ -121,13 +123,13 @@ class ApiEndpointItem(Generic[_M]): """ - def __init__(self, app: 'Framework', endpoint: str, id: str): + def __init__(self, app: Framework, endpoint: str, id: str): self.app = app self.endpoint = endpoint self.id = id @cached_property - def api_endpoint(self) -> 'ApiEndpoint[_M] | None': + def api_endpoint(self) -> ApiEndpoint[_M] | None: cls = ApiEndpointCollection(self.app).endpoints.get(self.endpoint) # type(cls(self.app)) == return cls(self.app) if cls else None @@ -150,7 +152,7 @@ def links(self) -> dict[str, Any] | None: return self.api_endpoint.item_links(item) return None - def form(self, request: 'CoreRequest') -> 'Form | None': + def form(self, request: CoreRequest) -> Form | None: if self.api_endpoint and (item := self.item): return self.api_endpoint.form(item, request) @@ -172,11 +174,11 @@ class ApiEndpoint(Generic[_M]): name: ClassVar[str] = '' # FIXME: Do we ever use this? endpoint: ClassVar[str] = '' filters: ClassVar[set[str]] = set() - form_class: ClassVar[type['Form'] | None] = None + form_class: ClassVar[type[Form] | None] = None def __init__( self, - app: 'Framework', + app: Framework, extra_parameters: dict[str, str | None] | None = None, page: int | None = None, ): @@ -185,7 +187,7 @@ def __init__( self.page = int(page) if page else page self.batch_size = 100 - def for_page(self, page: int | None) -> 'Self | None': + def for_page(self, page: int | None) -> Self | None: """ Return a new endpoint instance with the given page while keeping the current filters. @@ -193,7 +195,7 @@ def for_page(self, page: int | None) -> 'Self | None': return self.__class__(self.app, self.extra_parameters, page) - def for_filter(self, **filters: Any) -> 'Self': + def for_filter(self, **filters: Any) -> Self: """ Return a new endpoint instance with the given filters while discarding the current filters and page. @@ -204,9 +206,9 @@ def for_filter(self, **filters: Any) -> 'Self': @overload def for_item(self, item: None) -> None: ... @overload - def for_item(self, item: _M) -> 'ApiEndpointItem[_M]': ... + def for_item(self, item: _M) -> ApiEndpointItem[_M]: ... - def for_item(self, item: _M | None) -> 'ApiEndpointItem[_M] | None': + def for_item(self, item: _M | None) -> ApiEndpointItem[_M] | None: """ Return a new endpoint item instance with the given item. """ if not item: @@ -222,17 +224,17 @@ def for_item(self, item: _M | None) -> 'ApiEndpointItem[_M] | None': def get_filter( self, name: str, - default: '_DefaultT', - empty: '_EmptyT' - ) -> 'str | _DefaultT | _EmptyT': ... + default: _DefaultT, + empty: _EmptyT + ) -> str | _DefaultT | _EmptyT: ... @overload def get_filter( self, name: str, - default: '_DefaultT', + default: _DefaultT, empty: None = None - ) -> 'str | _DefaultT | None': ... + ) -> str | _DefaultT | None: ... @overload def get_filter( @@ -240,8 +242,8 @@ def get_filter( name: str, default: None = None, *, - empty: '_EmptyT' - ) -> 'str | _EmptyT | None': ... + empty: _EmptyT + ) -> str | _EmptyT | None: ... @overload def get_filter( @@ -264,7 +266,7 @@ def get_filter( return default return self.extra_parameters[name] or empty - def by_id(self, id: 'PKType') -> _M | None: + def by_id(self, id: PKType) -> _M | None: """ Return the item with the given ID from the collection. """ try: @@ -273,11 +275,11 @@ def by_id(self, id: 'PKType') -> _M | None: return None @property - def session(self) -> 'Session': + def session(self) -> Session: return self.app.session() @property - def links(self) -> dict[str, 'Self | None']: + def links(self) -> dict[str, Self | None]: """ Returns a dictionary with pagination instances. """ result: dict[str, Self | None] = {'prev': None, 'next': None} @@ -291,7 +293,7 @@ def links(self) -> dict[str, 'Self | None']: return result @property - def batch(self) -> dict['ApiEndpointItem[_M]', _M]: + def batch(self) -> dict[ApiEndpointItem[_M], _M]: """ Returns a dictionary with endpoint item instances and their titles. @@ -334,8 +336,8 @@ def item_links(self, item: _M) -> dict[str, Any]: def form( self, item: _M | None, - request: 'CoreRequest' - ) -> 'Form | None': + request: CoreRequest + ) -> Form | None: """ Return a form for editing items of this collection. """ if self.form_class is None: @@ -414,7 +416,7 @@ def apply_changes(self, item: _M, form: Any) -> None: raise NotImplementedError() @property - def collection(self) -> 'PaginationWithById[_M, Any]': + def collection(self) -> PaginationWithById[_M, Any]: """ Return an instance of the collection with filters and page set. """ @@ -430,7 +432,7 @@ def assert_valid_filter(self, param: str) -> None: class ApiEndpointCollection: """ A collection of all available API endpoints. """ - def __init__(self, app: 'Framework'): + def __init__(self, app: Framework): self.app = app @cached_property @@ -443,7 +445,7 @@ def endpoints(self) -> dict[str, type[ApiEndpoint[Any]]]: class AuthEndpoint: - def __init__(self, app: 'Framework'): + def __init__(self, app: Framework): self.app = app @@ -451,7 +453,7 @@ class ApiKey(Base): __tablename__ = 'api_keys' - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type: ignore[arg-type] nullable=False, primary_key=True, @@ -459,14 +461,14 @@ class ApiKey(Base): ) #: the id of the user that created the api key - user_id: 'Column[uuid.UUID]' = Column( + user_id: Column[uuid.UUID] = Column( UUID, # type: ignore[arg-type] ForeignKey('users.id'), nullable=False ) #: the user that created the api key - user: 'relationship[User]' = relationship( + user: relationship[User] = relationship( User, backref=backref( 'api_keys', cascade='all,delete-orphan', lazy='dynamic' @@ -474,16 +476,16 @@ class ApiKey(Base): ) #: the name of the api key, may be any string - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: whether or not the api key can submit changes - read_only: 'Column[bool]' = Column(Boolean, default=True, nullable=False) + read_only: Column[bool] = Column(Boolean, default=True, nullable=False) #: the last time a token was generated based on this api key - last_used: 'Column[datetime | None]' = Column(UTCDateTime, nullable=True) + last_used: Column[datetime | None] = Column(UTCDateTime, nullable=True) #: the key itself - key: 'Column[uuid.UUID]' = Column( + key: Column[uuid.UUID] = Column( UUID, # type: ignore[arg-type] nullable=False, default=uuid4 diff --git a/src/onegov/api/path.py b/src/onegov/api/path.py index 5137f17d2e..bc6c6a3fd4 100644 --- a/src/onegov/api/path.py +++ b/src/onegov/api/path.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.api import ApiApp from onegov.api.models import ApiEndpoint, AuthEndpoint from onegov.api.models import ApiEndpointCollection @@ -14,7 +16,7 @@ model=ApiEndpointCollection, path='/api' ) -def get_api_endpoints(app: 'Framework') -> ApiEndpointCollection: +def get_api_endpoints(app: Framework) -> ApiEndpointCollection: return ApiEndpointCollection(app) @@ -24,11 +26,11 @@ def get_api_endpoints(app: 'Framework') -> ApiEndpointCollection: converters={'page': int} ) def get_api_endpoint( - app: 'Framework', + app: Framework, endpoint: str, page: int = 0, extra_parameters: dict[str, Any] | None = None, -) -> 'ApiEndpoint[Any] | AuthEndpoint': +) -> ApiEndpoint[Any] | AuthEndpoint: if endpoint == 'authenticate': return AuthEndpoint(app) @@ -44,7 +46,7 @@ def get_api_endpoint( path='/api/{endpoint}/{id}', ) def get_api_endpoint_item( - app: 'Framework', endpoint: str, id: str + app: Framework, endpoint: str, id: str ) -> ApiEndpointItem[Any]: item: ApiEndpointItem[Any] = ApiEndpointItem(app, endpoint, id) if not item.api_endpoint or not item.item: # for ex. ExtendedAgency diff --git a/src/onegov/api/token.py b/src/onegov/api/token.py index 66619514a1..b3388bd432 100644 --- a/src/onegov/api/token.py +++ b/src/onegov/api/token.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import jwt from base64 import b64decode @@ -12,11 +14,11 @@ from onegov.core.request import CoreRequest -def jwt_decode(request: 'CoreRequest', token: str | bytes) -> Any: +def jwt_decode(request: CoreRequest, token: str | bytes) -> Any: return jwt.decode(token, request.identity_secret, algorithms=['HS512']) -def jwt_encode(request: 'CoreRequest', payload: dict[str, Any]) -> str: +def jwt_encode(request: CoreRequest, payload: dict[str, Any]) -> str: iat = utcnow() # This has to be UTC, # not local @@ -27,7 +29,7 @@ def jwt_encode(request: 'CoreRequest', payload: dict[str, Any]) -> str: return jwt.encode(payload, request.identity_secret, algorithm='HS512') -def get_token(request: 'CoreRequest') -> dict[str, str]: +def get_token(request: CoreRequest) -> dict[str, str]: key = try_get_encoded_token(request) @@ -40,7 +42,7 @@ def get_token(request: 'CoreRequest') -> dict[str, str]: return {'token': jwt_encode(request, payload)} -def try_get_encoded_token(request: 'CoreRequest') -> str: +def try_get_encoded_token(request: CoreRequest) -> str: assert request.authorization is not None assert isinstance(request.authorization.params, str) if request.authorization.authtype == 'Basic': diff --git a/src/onegov/api/utils.py b/src/onegov/api/utils.py index cf9e96248f..98c48c92e9 100644 --- a/src/onegov/api/utils.py +++ b/src/onegov/api/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import jwt from datetime import timedelta @@ -16,7 +18,7 @@ # TODO: Do we allow this to update request.identity, so we can elevate # privileges for what a given API token is allowed to see? -def authenticate(request: 'CoreRequest') -> ApiKey: +def authenticate(request: CoreRequest) -> ApiKey: if request.authorization is None: raise HTTPUnauthorized() @@ -34,7 +36,7 @@ def authenticate(request: 'CoreRequest') -> ApiKey: return api_key -def check_rate_limit(request: 'CoreRequest') -> dict[str, str]: +def check_rate_limit(request: CoreRequest) -> dict[str, str]: """ Checks if the rate limit for the current client. Raises an exception if the rate limit is reached. Returns response headers @@ -76,7 +78,7 @@ def check_rate_limit(request: 'CoreRequest') -> dict[str, str]: } @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: for header in headers.items(): response.headers.add(*header) diff --git a/src/onegov/api/views.py b/src/onegov/api/views.py index dbcd129cd9..6db66517db 100644 --- a/src/onegov/api/views.py +++ b/src/onegov/api/views.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.api import ApiApp from onegov.api.models import ApiEndpoint, ApiException, AuthEndpoint from onegov.api.models import ApiEndpointCollection @@ -21,11 +23,11 @@ @ApiApp.json(model=ApiException, permission=Public) def handle_exception( - self: ApiException, request: 'CoreRequest' + self: ApiException, request: CoreRequest ) -> dict[str, dict[str, dict[str, Any] | str]]: @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: response.status_code = self.status_code response.headers['Content-Type'] = 'application/vnd.collection+json' for name, value in self.headers.items(): @@ -45,10 +47,10 @@ def add_headers(response: 'Response') -> None: permission=Public ) def view_api_endpoints( - self: ApiEndpointCollection, request: 'CoreRequest' + self: ApiEndpointCollection, request: CoreRequest ) -> dict[str, Any]: @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: response.headers['Content-Type'] = 'application/vnd.collection+json' return { @@ -75,13 +77,13 @@ def add_headers(response: 'Response') -> None: permission=Public ) def view_api_endpoint( - self: 'ApiEndpoint[Any]', request: 'CoreRequest' + self: ApiEndpoint[Any], request: CoreRequest ) -> dict[str, Any]: headers = check_rate_limit(request) @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: response.headers['Content-Type'] = 'application/vnd.collection+json' try: @@ -143,12 +145,12 @@ def add_headers(response: 'Response') -> None: permission=Public ) def view_api_endpoint_item( - self: ApiEndpointItem[Any], request: 'CoreRequest' + self: ApiEndpointItem[Any], request: CoreRequest ) -> dict[str, Any]: headers = check_rate_limit(request) @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: response.headers['Content-Type'] = 'application/vnd.collection+json' try: @@ -213,7 +215,7 @@ def add_headers(response: 'Response') -> None: request_method='PUT' ) def edit_api_endpoint_item( - self: ApiEndpointItem[Any], request: 'CoreRequest' + self: ApiEndpointItem[Any], request: CoreRequest ) -> None: endpoint = self.api_endpoint @@ -234,9 +236,9 @@ def edit_api_endpoint_item( raise HTTPNotFound() def walk_errors( - errors: 'Sequence[str] | _FormErrors', + errors: Sequence[str] | _FormErrors, prefix: str | None - ) -> 'Generator[tuple[str | None, str]]': + ) -> Generator[tuple[str | None, str]]: if isinstance(errors, dict): for suffix, errs in errors.items(): @@ -266,7 +268,7 @@ def walk_errors( @ApiApp.json(model=AuthEndpoint, permission=Public) def get_time_restricted_token( - self: AuthEndpoint, request: 'CoreRequest' + self: AuthEndpoint, request: CoreRequest ) -> dict[str, str]: try: if request.authorization is None: diff --git a/src/onegov/async_http/fetch.py b/src/onegov/async_http/fetch.py index 887dc9f1f4..ab8db3a24e 100644 --- a/src/onegov/async_http/fetch.py +++ b/src/onegov/async_http/fetch.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import asyncio from aiohttp import ClientSession, ClientTimeout @@ -30,47 +32,47 @@ def raise_by_default(url: Any, exception: Exception) -> None: raise exception -def default_callback(url: 'UrlType', response: Any) -> tuple['UrlType', Any]: +def default_callback(url: UrlType, response: Any) -> tuple[UrlType, Any]: return url, response @overload async def fetch( - url: 'UrlType', + url: UrlType, session: ClientSession, response_attr: str = 'json', - callback: 'FetchCallback[UrlType, tuple[UrlType, Any]]' = default_callback, - handle_exceptions: 'ErrFunc[UrlType] | None' = raise_by_default -) -> tuple['UrlType', Any]: ... + callback: FetchCallback[UrlType, tuple[UrlType, Any]] = default_callback, + handle_exceptions: ErrFunc[UrlType] | None = raise_by_default +) -> tuple[UrlType, Any]: ... @overload async def fetch( - url: 'UrlType', + url: UrlType, session: ClientSession, response_attr: str, - callback: 'FetchCallback[_UrlTypeT, _T]', - handle_exceptions: 'ErrFunc[_UrlTypeT] | None' = raise_by_default -) -> '_T': ... + callback: FetchCallback[_UrlTypeT, _T], + handle_exceptions: ErrFunc[_UrlTypeT] | None = raise_by_default +) -> _T: ... @overload async def fetch( - url: 'UrlType', + url: UrlType, session: ClientSession, response_attr: str = 'json', *, - callback: 'FetchCallback[_UrlTypeT, _T]', - handle_exceptions: 'ErrFunc[_UrlTypeT] | None' = raise_by_default -) -> '_T': ... + callback: FetchCallback[_UrlTypeT, _T], + handle_exceptions: ErrFunc[_UrlTypeT] | None = raise_by_default +) -> _T: ... async def fetch( - url: 'UrlType', + url: UrlType, session: ClientSession, response_attr: str = 'json', - callback: 'FetchCallback[Any, Any]' = default_callback, - handle_exceptions: 'ErrFunc[Any] | None' = raise_by_default + callback: FetchCallback[Any, Any] = default_callback, + handle_exceptions: ErrFunc[Any] | None = raise_by_default ) -> Any: """ Asynchronous get request. Pass handle_exceptions in order to get your @@ -102,44 +104,44 @@ async def fetch( @overload async def fetch_many( - urls: 'Sequence[UrlType]', + urls: Sequence[UrlType], response_attr: str = 'json', - fetch_func: 'FetchFunc[UrlType, tuple[UrlType, Any]]' = fetch, - callback: 'FetchCallback[UrlType, tuple[UrlType, Any]]' = default_callback, - handle_exceptions: 'HandleExceptionType[UrlType]' = raise_by_default, + fetch_func: FetchFunc[UrlType, tuple[UrlType, Any]] = fetch, + callback: FetchCallback[UrlType, tuple[UrlType, Any]] = default_callback, + handle_exceptions: HandleExceptionType[UrlType] = raise_by_default, timeout: ClientTimeout | None = None -) -> list[tuple['UrlType', Any]]: ... +) -> list[tuple[UrlType, Any]]: ... @overload async def fetch_many( - urls: 'Sequence[UrlType]', + urls: Sequence[UrlType], response_attr: str, - fetch_func: 'FetchFunc[_UrlTypeT, _T]', - callback: 'FetchCallback[_UrlTypeT, _T]', - handle_exceptions: 'HandleExceptionType[_UrlTypeT]' = raise_by_default, + fetch_func: FetchFunc[_UrlTypeT, _T], + callback: FetchCallback[_UrlTypeT, _T], + handle_exceptions: HandleExceptionType[_UrlTypeT] = raise_by_default, timeout: ClientTimeout | None = None -) -> list['_T']: ... +) -> list[_T]: ... @overload async def fetch_many( - urls: 'Sequence[UrlType]', + urls: Sequence[UrlType], response_attr: str = 'json', - fetch_func: 'FetchFunc[_UrlTypeT, _T]' = fetch, + fetch_func: FetchFunc[_UrlTypeT, _T] = fetch, *, - callback: 'FetchCallback[_UrlTypeT, _T]', - handle_exceptions: 'HandleExceptionType[_UrlTypeT]' = raise_by_default, + callback: FetchCallback[_UrlTypeT, _T], + handle_exceptions: HandleExceptionType[_UrlTypeT] = raise_by_default, timeout: ClientTimeout | None = None -) -> list['_T']: ... +) -> list[_T]: ... async def fetch_many( - urls: 'Sequence[UrlType]', + urls: Sequence[UrlType], response_attr: str = 'json', - fetch_func: 'FetchFunc[Any, Any]' = fetch, - callback: 'FetchCallback[Any, Any]' = default_callback, - handle_exceptions: 'HandleExceptionType[Any]' = raise_by_default, + fetch_func: FetchFunc[Any, Any] = fetch, + callback: FetchCallback[Any, Any] = default_callback, + handle_exceptions: HandleExceptionType[Any] = raise_by_default, timeout: ClientTimeout | None = None ) -> list[Any]: """ Registers a task per url using the coroutine fetch_func with correct @@ -165,40 +167,40 @@ def exception_handler(ix: int) -> Any: @overload def async_aiohttp_get_all( - urls: 'Sequence[UrlType]', + urls: Sequence[UrlType], response_attr: str = 'json', - callback: 'FetchCallback[UrlType, tuple[UrlType, Any]]' = default_callback, - handle_exceptions: 'HandleExceptionType[UrlType]' = raise_by_default, + callback: FetchCallback[UrlType, tuple[UrlType, Any]] = default_callback, + handle_exceptions: HandleExceptionType[UrlType] = raise_by_default, timeout: ClientTimeout | None = None -) -> list[tuple['UrlType', Any]]: ... +) -> list[tuple[UrlType, Any]]: ... @overload def async_aiohttp_get_all( - urls: 'Sequence[UrlType]', + urls: Sequence[UrlType], response_attr: str, - callback: 'FetchCallback[_UrlTypeT, _T]', - handle_exceptions: 'HandleExceptionType[_UrlTypeT]' = raise_by_default, + callback: FetchCallback[_UrlTypeT, _T], + handle_exceptions: HandleExceptionType[_UrlTypeT] = raise_by_default, timeout: ClientTimeout | None = None -) -> list['_T']: ... +) -> list[_T]: ... @overload def async_aiohttp_get_all( - urls: 'Sequence[UrlType]', + urls: Sequence[UrlType], response_attr: str = 'json', *, - callback: 'FetchCallback[_UrlTypeT, _T]', - handle_exceptions: 'HandleExceptionType[_UrlTypeT]' = raise_by_default, + callback: FetchCallback[_UrlTypeT, _T], + handle_exceptions: HandleExceptionType[_UrlTypeT] = raise_by_default, timeout: ClientTimeout | None = None -) -> list['_T']: ... +) -> list[_T]: ... def async_aiohttp_get_all( - urls: 'Sequence[_UrlTypeT]', + urls: Sequence[_UrlTypeT], response_attr: str = 'json', - callback: 'FetchCallback[Any, Any]' = default_callback, - handle_exceptions: 'HandleExceptionType[Any]' = raise_by_default, + callback: FetchCallback[Any, Any] = default_callback, + handle_exceptions: HandleExceptionType[Any] = raise_by_default, timeout: ClientTimeout | None = None ) -> list[Any]: """ Performs asynchronous get requests. diff --git a/src/onegov/chat/__init__.py b/src/onegov/chat/__init__.py index 3ee672efd5..7bd4c157a0 100644 --- a/src/onegov/chat/__init__.py +++ b/src/onegov/chat/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.chat.models import Message, MessageFile, TextModule from onegov.chat.collections import MessageCollection, TextModuleCollection diff --git a/src/onegov/chat/collections/__init__.py b/src/onegov/chat/collections/__init__.py index b6ab44d628..f96c0d487d 100644 --- a/src/onegov/chat/collections/__init__.py +++ b/src/onegov/chat/collections/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.chat.collections.message import MessageCollection from onegov.chat.collections.text_module import TextModuleCollection from onegov.chat.collections.chat import ChatCollection diff --git a/src/onegov/chat/collections/chat.py b/src/onegov/chat/collections/chat.py index 38a777c2da..d5f3f221b1 100644 --- a/src/onegov/chat/collections/chat.py +++ b/src/onegov/chat/collections/chat.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.chat.models import Chat from onegov.core.collection import GenericCollection, Pagination @@ -19,7 +21,7 @@ class ChatCollection(GenericCollection[Chat], Pagination[Chat]): def __init__( self, - session: 'Session', + session: Session, page: int = 0, state: str = 'active', group: str | None = None, @@ -34,7 +36,7 @@ def __init__( def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) and self.page == other.page - def subset(self) -> 'Query[Chat]': + def subset(self) -> Query[Chat]: query = self.query().filter(Chat.chat_history != []).order_by( Chat.last_change.desc()) if self.state == 'active': @@ -48,7 +50,7 @@ def subset(self) -> 'Query[Chat]': def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__( self.session, page=index, diff --git a/src/onegov/chat/collections/message.py b/src/onegov/chat/collections/message.py index 262dac9e38..945100d0f1 100644 --- a/src/onegov/chat/collections/message.py +++ b/src/onegov/chat/collections/message.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.chat.models import Message from onegov.core.collection import GenericCollection from sqlalchemy import desc @@ -17,8 +19,8 @@ class MessageCollection(GenericCollection[_M]): @overload def __init__( - self: 'MessageCollection[Message]', - session: 'Session', + self: MessageCollection[Message], + session: Session, type: tuple[str, ...] | Literal['*'] | None = ..., channel_id: str = '*', newer_than: str | None = None, @@ -30,7 +32,7 @@ def __init__( @overload def __init__( self, - session: 'Session', + session: Session, type: str, channel_id: str = '*', newer_than: str | None = None, @@ -41,7 +43,7 @@ def __init__( def __init__( self, - session: 'Session', + session: Session, type: str | tuple[str, ...] | None = '*', channel_id: str = '*', newer_than: str | None = None, @@ -74,9 +76,9 @@ def add( type: str | None = None, meta: dict[str, Any] = ..., text: str | None = None, - created: 'datetime' = ..., - updated: 'datetime | None' = ..., - file: 'MessageFile | None' = None, + created: datetime = ..., + updated: datetime | None = ..., + file: MessageFile | None = None, **kwargs: Any ) -> _M: ... @@ -104,7 +106,7 @@ def add( return super().add(type=_type, **kwargs) - def query(self) -> 'Query[_M]': + def query(self) -> Query[_M]: """ Queries the messages with the given parameters. """ q = self.session.query(self.model_class) diff --git a/src/onegov/chat/collections/text_module.py b/src/onegov/chat/collections/text_module.py index ac2b735d79..60b537c6c1 100644 --- a/src/onegov/chat/collections/text_module.py +++ b/src/onegov/chat/collections/text_module.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.chat.models import TextModule from onegov.core.collection import GenericCollection from sqlalchemy import or_ @@ -12,7 +14,7 @@ class TextModuleCollection(GenericCollection[TextModule]): def __init__( self, - session: 'Session', + session: Session, type: str = '*', handler: str = 'ALL', owner: str = '*' @@ -26,7 +28,7 @@ def __init__( def model_class(self) -> type[TextModule]: return TextModule - def query(self) -> 'Query[TextModule]': + def query(self) -> Query[TextModule]: query = super().query() if self.owner != '*': diff --git a/src/onegov/chat/models/__init__.py b/src/onegov/chat/models/__init__.py index 7735e20167..ed6c356717 100644 --- a/src/onegov/chat/models/__init__.py +++ b/src/onegov/chat/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.chat.models.message import Message, MessageFile from onegov.chat.models.text_module import TextModule from onegov.chat.models.chat import Chat diff --git a/src/onegov/chat/models/chat.py b/src/onegov/chat/models/chat.py index 41318910b1..479a39d799 100644 --- a/src/onegov/chat/models/chat.py +++ b/src/onegov/chat/models/chat.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -23,7 +25,7 @@ class Chat(Base, TimestampMixin): #: subclasses of this class. See #: ``_. - type: 'Column[str]' = Column( + type: Column[str] = Column( Text, nullable=False, default=lambda: 'generic' @@ -35,23 +37,23 @@ class Chat(Base, TimestampMixin): } #: the unique id, part of the url - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) - user_id: 'Column[uuid.UUID | None]' = Column( + user_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey('users.id'), nullable=True ) - user: 'relationship[User | None]' = relationship(User) + user: relationship[User | None] = relationship(User) - customer_name: 'Column[str]' = Column(Text, nullable=False) - email: 'Column[str]' = Column(Text, nullable=False) - topic: 'Column[str]' = Column(Text, nullable=False) - active: 'Column[bool]' = Column(Boolean, nullable=False, default=True) - chat_history: 'Column[list[dict[str, Any]]]' = Column( + customer_name: Column[str] = Column(Text, nullable=False) + email: Column[str] = Column(Text, nullable=False) + topic: Column[str] = Column(Text, nullable=False) + active: Column[bool] = Column(Boolean, nullable=False, default=True) + chat_history: Column[list[dict[str, Any]]] = Column( JSONB, # type:ignore[arg-type] nullable=False, default=list diff --git a/src/onegov/chat/models/message.py b/src/onegov/chat/models/message.py index ec9e372221..3c2d229339 100644 --- a/src/onegov/chat/models/message.py +++ b/src/onegov/chat/models/message.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate from onegov.core.orm import Base @@ -35,7 +37,7 @@ class Message(Base): __tablename__ = 'messages' #: the public id of the message - uses ulid for absolute ordering - id: 'Column[str]' = Column( + id: Column[str] = Column( Text, primary_key=True, default=lambda: str(ULID()) @@ -44,31 +46,31 @@ class Message(Base): #: channel to which this message belongs -> this might one day be #: linked to an actual channel record - for now it's just a string that #: binds all messages with the same string together - channel_id: 'Column[str]' = Column(Text, index=True, nullable=False) + channel_id: Column[str] = Column(Text, index=True, nullable=False) #: optional owner of the message -> this is just an identifier, it isn't #: necessarily linked to the user table - owner: 'Column[str | None]' = Column(Text, nullable=True) + owner: Column[str | None] = Column(Text, nullable=True) #: the polymorphic type of the message - type: 'Column[str | None]' = Column(Text, nullable=True) + type: Column[str | None] = Column(Text, nullable=True) #: meta information specific to this message and maybe its type -> we #: don't use the meta/content mixin yet as we might not need the content #: property - meta: 'Column[dict[str, Any]]' = Column(JSON, nullable=False, default=dict) + meta: Column[dict[str, Any]] = Column(JSON, nullable=False, default=dict) #: the text of the message, maybe None for certain use cases (say if the # content of the message is generated from the meta property) - text: 'Column[str | None]' = Column(Text, nullable=True) + text: Column[str | None] = Column(Text, nullable=True) #: the time this message was created - not taken from the timestamp mixin #: because here we don't want it to be deferred - created: 'Column[datetime]' = Column(UTCDateTime, default=sedate.utcnow) + created: Column[datetime] = Column(UTCDateTime, default=sedate.utcnow) #: the time this message was modified - not taken from the timestamp mixin #: because here we don't want it to be deferred - modified: 'Column[datetime | None]' = Column( + modified: Column[datetime | None] = Column( UTCDateTime, onupdate=sedate.utcnow ) @@ -103,7 +105,7 @@ def subtype(self) -> str | None: """ return None - def get(self, request: 'CoreRequest') -> str | None: + def get(self, request: CoreRequest) -> str | None: """ Code rendering a message should call this method to get the actual text of the message. It might be rendered from meta or it might be returned directly from the text column. @@ -123,7 +125,7 @@ def edited(self) -> bool: return self.modified != None @classmethod - def bound_messages(cls, session: 'Session') -> 'MessageCollection[Self]': + def bound_messages(cls, session: Session) -> MessageCollection[Self]: """ A message collection bound to the polymorphic identity of this message. @@ -136,7 +138,7 @@ def bound_messages(cls, session: 'Session') -> 'MessageCollection[Self]': ) -@event.listens_for(Message, 'init') +@event.listens_for(Message, 'init') # type:ignore[misc] def init( target: Message, args: tuple[Any, ...], diff --git a/src/onegov/chat/models/text_module.py b/src/onegov/chat/models/text_module.py index 66cfe0a38b..f7f756c640 100644 --- a/src/onegov/chat/models/text_module.py +++ b/src/onegov/chat/models/text_module.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -27,46 +29,46 @@ class TextModule(Base, TimestampMixin): __tablename__ = 'text_modules' #: the public id of the text module - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the name of the text module - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: the actual text module - text: 'Column[str]' = Column(Text, nullable=False) + text: Column[str] = Column(Text, nullable=False) #: the message type this text module should be available for - message_type: 'Column[str | None]' = Column( + message_type: Column[str | None] = Column( Text, nullable=True, index=True ) #: the ticket handler this text module should be available for - handler_code: 'Column[str | None]' = Column( + handler_code: Column[str | None] = Column( Text, nullable=True, index=True ) #: for a private text module the user it belongs to - user_id: 'Column[uuid.UUID | None]' = Column( + user_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey(User.id), nullable=True ) - user: 'relationship[User | None]' = relationship(User) + user: relationship[User | None] = relationship(User) @property def private(self) -> bool: return self.user_id is not None @property - def formatted_text(self) -> 'Markup': + def formatted_text(self) -> Markup: return paragraphify(linkify(self.text)) @property diff --git a/src/onegov/chat/upgrade.py b/src/onegov/chat/upgrade.py index e58cd8ef81..e5ef0c194d 100644 --- a/src/onegov/chat/upgrade.py +++ b/src/onegov/chat/upgrade.py @@ -2,6 +2,7 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations from typing import TYPE_CHECKING @@ -14,7 +15,7 @@ @upgrade_task('Add messages column and remove others1') -def add_messages_column_and_remove_others1(context: 'UpgradeContext') -> None: +def add_messages_column_and_remove_others1(context: UpgradeContext) -> None: if not context.has_column('chats', 'messages'): context.operations.add_column('chats', Column('messages', Text)) if context.has_column('chats', 'publication_start'): diff --git a/src/onegov/chat/utils.py b/src/onegov/chat/utils.py index cdecf9172c..d64d6b945a 100644 --- a/src/onegov/chat/utils.py +++ b/src/onegov/chat/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from urllib.parse import parse_qs, urlparse diff --git a/src/onegov/core/__init__.py b/src/onegov/core/__init__.py index 8d831b5c2c..1be7a63b16 100644 --- a/src/onegov/core/__init__.py +++ b/src/onegov/core/__init__.py @@ -5,7 +5,9 @@ # version is to create release-dependent urls, artifacts and caches. During # development these dependencies do not need to be updated in lock-step. # -__version__ = '2024.60' +from __future__ import annotations + +__version__ = '2025.1' # The module levels used for dependency tests and to have a well defined # onegov core upgrade order. diff --git a/src/onegov/core/browser_session.py b/src/onegov/core/browser_session.py index 58f4a047b9..4822b68daf 100644 --- a/src/onegov/core/browser_session.py +++ b/src/onegov/core/browser_session.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from contextlib import suppress from dogpile.cache.api import NO_VALUE from hashlib import blake2b @@ -18,7 +20,7 @@ class Prefixed: - def __init__(self, prefix: str, cache: 'RedisCacheRegion'): + def __init__(self, prefix: str, cache: RedisCacheRegion): assert len(prefix) >= 24 self.prefix = prefix @@ -78,9 +80,9 @@ class BrowserSession: def __init__( self, - cache: 'RedisCacheRegion', + cache: RedisCacheRegion, token: str, - on_dirty: 'OnDirtyCallback' = lambda session, token: None + on_dirty: OnDirtyCallback = lambda session, token: None ): # make it impossible to get the session token through key listing @@ -141,7 +143,7 @@ def get(self, name: str, default: Any = None) -> Any: # FIXME: What is *args for, why do we allow this? For now we set # it to Never, so we get a mypy error, if there is any code # that uses this, if no code uses it then get rid of it! - def __getitem__(self, name: str, *args: 'Never') -> Any: + def __getitem__(self, name: str, *args: Never) -> Any: result = self._cache.get(name) if result is NO_VALUE: diff --git a/src/onegov/core/cache.py b/src/onegov/core/cache.py index 8d9ae78437..1b0c7331b3 100644 --- a/src/onegov/core/cache.py +++ b/src/onegov/core/cache.py @@ -33,6 +33,7 @@ def my_view(): eventually be discarded by redis if the cache is full). """ +from __future__ import annotations import dill # type:ignore[import-untyped] @@ -54,19 +55,19 @@ def my_view(): @overload -def instance_lru_cache(*, maxsize: int | None = ...) -> 'Callable[[_F], _F]': +def instance_lru_cache(*, maxsize: int | None = ...) -> Callable[[_F], _F]: ... @overload -def instance_lru_cache(method: '_F', *, maxsize: int | None = ...) -> '_F': ... +def instance_lru_cache(method: _F, *, maxsize: int | None = ...) -> _F: ... def instance_lru_cache( - method: '_F | None' = None, + method: _F | None = None, *, maxsize: int | None = 128 -) -> '_F | Callable[[_F], _F]': +) -> _F | Callable[[_F], _F]: """ Least-recently-used cache decorator for class methods. The cache follows the lifetime of an object (it is stored on the object, @@ -79,7 +80,7 @@ def instance_lru_cache( """ - def decorator(wrapped: '_F') -> '_F': + def decorator(wrapped: _F) -> _F: def wrapper(self: Any) -> Any: return lru_cache(maxsize=maxsize)( update_wrapper(partial(wrapped, self), wrapped) @@ -100,7 +101,7 @@ def dill_serialize(value: Any) -> bytes: return dill.dumps(value, recurse=True) -def dill_deserialize(value: 'bytes | NoValue') -> Any: +def dill_deserialize(value: bytes | NoValue) -> Any: if value is NO_VALUE: return value return dill.loads(value) # nosec:B301 diff --git a/src/onegov/core/cli/__init__.py b/src/onegov/core/cli/__init__.py index 99efec9fc1..ab6283f3b5 100644 --- a/src/onegov/core/cli/__init__.py +++ b/src/onegov/core/cli/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.cli.commands import cli from onegov.core.cli.core import ( abort, diff --git a/src/onegov/core/cli/commands.py b/src/onegov/core/cli/commands.py index 8e15e9e61c..90c2f3f5b4 100644 --- a/src/onegov/core/cli/commands.py +++ b/src/onegov/core/cli/commands.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import click import os import platform @@ -56,15 +58,15 @@ @cli.command() @pass_group_context def delete( - group_context: 'GroupContext' -) -> 'Callable[[CoreRequest, Framework], None]': + group_context: GroupContext +) -> Callable[[CoreRequest, Framework], None]: """ Deletes a single instance matching the selector. Selectors matching multiple organisations are disabled for saftey reasons. """ - def delete_instance(request: 'CoreRequest', app: 'Framework') -> None: + def delete_instance(request: CoreRequest, app: Framework) -> None: confirmation = 'Do you really want to DELETE this instance?' @@ -118,7 +120,7 @@ def delete_instance(request: 'CoreRequest', app: 'Framework') -> None: @click.option('--limit', default=25, help='Max number of mails to send before exiting') @pass_group_context -def sendmail(group_context: 'GroupContext', queue: str, limit: int) -> None: +def sendmail(group_context: GroupContext, queue: str, limit: int) -> None: """ Sends mail from a specific mail queue. """ queues = group_context.config.mail_queues @@ -161,8 +163,8 @@ def sendmail(group_context: 'GroupContext', queue: str, limit: int) -> None: }) @pass_group_context def sendsms( - group_context: 'GroupContext' -) -> 'Callable[[CoreRequest, Framework], None]': + group_context: GroupContext +) -> Callable[[CoreRequest, Framework], None]: """ Sends the SMS in the smsdir for a given instance. For example:: @@ -171,7 +173,7 @@ def sendsms( """ - def send(request: 'CoreRequest', app: 'Framework') -> None: + def send(request: CoreRequest, app: Framework) -> None: qp = get_sms_queue_processor(app) if qp is None: return @@ -190,7 +192,7 @@ def __init__(self, queue_processors: list[SmsQueueProcessor]): ignore_directories=True ) - def on_moved(self, event: 'FileSystemEvent') -> None: + def on_moved(self, event: FileSystemEvent) -> None: dest_path = os.path.abspath(str(event.dest_path)) assert isinstance(dest_path, str) for qp in self.queue_processors: @@ -208,7 +210,7 @@ def on_moved(self, event: 'FileSystemEvent') -> None: # move since our DataManager creates a temporary file that then is # moved. But we should also trigger when new files are created just # in case this ever changes. - def on_created(self, event: 'FileSystemEvent') -> None: + def on_created(self, event: FileSystemEvent) -> None: src_path = os.path.abspath(str(event.src_path)) assert isinstance(src_path, str) for qp in self.queue_processors: @@ -228,7 +230,7 @@ def on_created(self, event: 'FileSystemEvent') -> None: 'default_selector': '*' }) @pass_group_context -def sms_spooler(group_context: 'GroupContext') -> None: +def sms_spooler(group_context: GroupContext) -> None: """ Continuously spools the SMS in the smsdir for all instances using a watchdog that monitors the smsdir for newly created files. @@ -240,8 +242,8 @@ def sms_spooler(group_context: 'GroupContext') -> None: queue_processors: dict[str, list[SmsQueueProcessor]] = defaultdict(list) def create_sms_queue_processor( - request: 'CoreRequest', - app: 'Framework' + request: CoreRequest, + app: Framework ) -> None: # we're fine if the path doesn't exist yet, we only call @@ -308,7 +310,7 @@ def create_sms_queue_processor( 'changed') @pass_group_context def transfer( - group_context: 'GroupContext', + group_context: GroupContext, server: str, remote_config: str, confirm: bool, @@ -604,9 +606,9 @@ def transfer_database( return schemas def transfer_storage_of_app( - local_cfg: 'ApplicationConfig', - remote_cfg: 'ApplicationConfig', - transfer_function: 'Callable[..., None]' + local_cfg: ApplicationConfig, + remote_cfg: ApplicationConfig, + transfer_function: Callable[..., None] ) -> None: remote_storage = remote_cfg.configuration.get('filestorage', '') @@ -625,9 +627,9 @@ def transfer_storage_of_app( transfer_function(remote_storage, local_storage, glob=glob) def transfer_depot_storage_of_app( - local_cfg: 'ApplicationConfig', - remote_cfg: 'ApplicationConfig', - transfer_function: 'Callable[..., None]' + local_cfg: ApplicationConfig, + remote_cfg: ApplicationConfig, + transfer_function: Callable[..., None] ) -> None: depot_local_storage = 'depot.io.local.LocalFileStorage' @@ -645,8 +647,8 @@ def transfer_depot_storage_of_app( transfer_function(remote_storage, local_storage, glob=glob) def transfer_database_of_app( - local_cfg: 'ApplicationConfig', - remote_cfg: 'ApplicationConfig' + local_cfg: ApplicationConfig, + remote_cfg: ApplicationConfig ) -> tuple[str, ...]: if 'dsn' not in remote_cfg.configuration: @@ -665,7 +667,7 @@ def transfer_database_of_app( schema_glob = transfer_schema or f'{local_cfg.namespace}*' return transfer_database(remote_db, local_db, schema_glob=schema_glob) - def do_add_admins(local_cfg: 'ApplicationConfig', schema: str) -> None: + def do_add_admins(local_cfg: ApplicationConfig, schema: str) -> None: id_ = str(uuid4()) password_hash = hash_password('test').replace('$', '\\$') assert '"' not in schema and "'" not in schema @@ -741,9 +743,9 @@ def do_add_admins(local_cfg: 'ApplicationConfig', schema: str) -> None: help='Do not write any changes into the database.') @pass_group_context def upgrade( - group_context: 'GroupContext', + group_context: GroupContext, dry_run: bool -) -> tuple['Callable[..., Any]', ...]: +) -> tuple[Callable[..., Any], ...]: """ Upgrades all application instances of the given namespace(s). """ modules = list(get_upgrade_modules()) @@ -754,10 +756,10 @@ def upgrade( basic_tasks = tuple((id, task) for id, task in tasks if not task.raw) raw_tasks = tuple((id, task) for id, task in tasks if task.raw) - def on_success(task: '_Task[..., Any]') -> None: + def on_success(task: _Task[..., Any]) -> None: print(click.style('* ' + str(task.task_name), fg='green')) - def on_fail(task: '_Task[..., Any]') -> None: + def on_fail(task: _Task[..., Any]) -> None: print(click.style('* ' + str(task.task_name), fg='red')) def run_upgrade_runner( @@ -772,8 +774,8 @@ def run_upgrade_runner( print('no pending upgrade tasks found') def run_raw_upgrade( - group_context: 'GroupContext', - appcfg: 'ApplicationConfig' + group_context: GroupContext, + appcfg: ApplicationConfig ) -> None: if appcfg in executed_raw_upgrades: @@ -797,7 +799,7 @@ def run_raw_upgrade( group_context.available_schemas(appcfg), ) - def run_upgrade(request: 'CoreRequest', app: 'Framework') -> None: + def run_upgrade(request: CoreRequest, app: Framework) -> None: title = 'Running upgrade for {}'.format(request.app.application_id) print(click.style(title, underline=True)) @@ -810,7 +812,7 @@ def run_upgrade(request: 'CoreRequest', app: 'Framework') -> None: ) run_upgrade_runner(upgrade_runner, request) - def upgrade_steps() -> 'Iterator[Callable[..., Any]]': + def upgrade_steps() -> Iterator[Callable[..., Any]]: if next((t for n, t in tasks if t.raw), False): yield run_raw_upgrade @@ -842,10 +844,10 @@ def init_completer(self) -> None: @cli.command() -def shell() -> 'Callable[[CoreRequest, Framework], None]': +def shell() -> Callable[[CoreRequest, Framework], None]: """ Enters an interactive shell. """ - def _shell(request: 'CoreRequest', app: 'Framework') -> None: + def _shell(request: CoreRequest, app: Framework) -> None: shell = EnhancedInteractiveConsole({ 'app': app, diff --git a/src/onegov/core/cli/core.py b/src/onegov/core/cli/core.py index 77d974158f..8045f63bf3 100644 --- a/src/onegov/core/cli/core.py +++ b/src/onegov/core/cli/core.py @@ -183,6 +183,7 @@ def my_click_command(): is not executed. """ +from __future__ import annotations import click import inspect @@ -206,6 +207,7 @@ def my_click_command(): from collections.abc import Callable, Collection, Iterator, Sequence from typing import Protocol, TypedDict + from onegov.core.framework import Framework from onegov.core.request import CoreRequest from onegov.core.security.permissions import Intent from onegov.server.config import ApplicationConfig @@ -218,7 +220,7 @@ class _GroupContextAttrs(Protocol): @property def available_selectors(self) -> list[str]: ... @property - def matches(self) -> 'Iterator[str]': ... + def matches(self) -> Iterator[str]: ... matches_required: bool singular: bool creates_path: bool @@ -260,7 +262,7 @@ def validate_guard_conditions(self, click_context: click.Context) -> None: def abort_if_no_selector( self, click_context: click.Context, - matches: 'Collection[str]' + matches: Collection[str] ) -> None: if not self.selector: @@ -274,7 +276,7 @@ def abort_if_no_selector( def abort_if_no_subcommand( self, click_context: click.Context, - matches: 'Collection[str]' + matches: Collection[str] ) -> None: if click_context.invoked_subcommand is None: @@ -288,7 +290,7 @@ def abort_if_no_subcommand( def abort_if_no_match( self, click_context: click.Context, - matches: 'Collection[str]' + matches: Collection[str] ) -> None: if self.matches_required and not matches: @@ -302,7 +304,7 @@ def abort_if_no_match( def abort_if_not_singular( self, click_context: click.Context, - matches: 'Collection[str]' + matches: Collection[str] ) -> None: if self.singular and len(matches) > 1: @@ -316,7 +318,7 @@ def abort_if_not_singular( def abort_if_no_create_path( self, click_context: click.Context, - matches: 'Collection[str]' + matches: Collection[str] ) -> None: if self.creates_path: @@ -390,7 +392,7 @@ def __init__( self.singular = singular self.matches_required = matches_required - def available_schemas(self, appcfg: 'ApplicationConfig') -> list[str]: + def available_schemas(self, appcfg: ApplicationConfig) -> list[str]: """ Returns all available schemas, if the application is database bound. @@ -425,7 +427,7 @@ def match_to_path(self, match: str) -> str | None: return None - def match_to_appcfg(self, match: str) -> 'ApplicationConfig | None': + def match_to_appcfg(self, match: str) -> ApplicationConfig | None: """ Takes the given match and returns the maching appcfg object. """ namespace, _id = self.split_match(match) @@ -437,7 +439,7 @@ def match_to_appcfg(self, match: str) -> 'ApplicationConfig | None': return None @property - def appcfgs(self) -> 'Iterator[ApplicationConfig]': + def appcfgs(self) -> Iterator[ApplicationConfig]: """ Returns the matching appconfigs. Since there's only one appconfig per namespace, we ignore the path @@ -470,7 +472,7 @@ def available_selectors(self) -> list[str]: return sorted(selectors) @property - def all_wildcard_selectors(self) -> 'Iterator[str]': + def all_wildcard_selectors(self) -> Iterator[str]: """ Returns all selectors targeting a namespace by wildcard. """ for appcfg in self.config.applications: @@ -478,7 +480,7 @@ def all_wildcard_selectors(self) -> 'Iterator[str]': yield '/' + appcfg.namespace + '/*' @property - def all_specific_selectors(self) -> 'Iterator[str]': + def all_specific_selectors(self) -> Iterator[str]: """ Returns all selectors targeting an application directly. """ for appcfg in self.config.applications: @@ -489,7 +491,7 @@ def all_specific_selectors(self) -> 'Iterator[str]': yield '/' + schema.replace('-', '/') @property - def matches(self) -> 'Iterator[str]': + def matches(self) -> Iterator[str]: """ Returns the specific selectors matching the context selector. That is, a combination of namespace / application id is returned. @@ -513,7 +515,7 @@ def matches(self) -> 'Iterator[str]': def get_context_specific_settings( context: click.Context -) -> 'ContextSpecificSettings': +) -> ContextSpecificSettings: """ Takes the given *click* context and extracts all context specific settings from it. @@ -549,7 +551,7 @@ def get_context_specific_settings( def run_processors( group_context: GroupContext, - processors: 'Sequence[Callable[..., Any]]' + processors: Sequence[Callable[..., Any]] ) -> None: """ Runs a sequence of processors either in a raw context or in a fully running application within a server. @@ -573,6 +575,7 @@ def run_processors( # below. processor = processors[0] + CliApplication: type[Framework] # noqa: N806 for appcfg in group_context.appcfgs: class CliApplication(appcfg.application_class): # type:ignore @@ -596,7 +599,7 @@ class Model: pass @CliApplication.view(model=Model, permission=Public) - def run_command(self: Model, request: 'CoreRequest') -> None: + def run_command(self: Model, request: CoreRequest) -> None: # NOTE: This is kind of fragile, this depends on the loop # variable 'processor' from the loop below, this works # because Python will look up the variable at the time @@ -608,7 +611,7 @@ def get_cronjobs_enabled() -> bool: return False @CliApplication.setting_section(section='roles') - def get_roles_setting() -> dict[str, set[type['Intent']]]: + def get_roles_setting() -> dict[str, set[type[Intent]]]: # override the security settings -> we need the public # role to work for anonymous users, even if the base # application disables that @@ -634,7 +637,7 @@ def get_roles_setting() -> dict[str, set[type['Intent']]]: configure_logging=False ) - def expects_request(processor: 'Callable[..., Any]') -> bool: + def expects_request(processor: Callable[..., Any]) -> bool: return 'request' in processor.__code__.co_varnames # call the matching applications @@ -699,7 +702,7 @@ def command_group(select: str | None, config: str) -> None: @command_group.result_callback() def process_results( - processor: 'Callable[..., Any] | Sequence[Callable[..., Any]]', + processor: Callable[..., Any] | Sequence[Callable[..., Any]], select: str, config: str ) -> None: diff --git a/src/onegov/core/collection.py b/src/onegov/core/collection.py index 25496688d5..3d590f56da 100644 --- a/src/onegov/core/collection.py +++ b/src/onegov/core/collection.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import math from functools import cached_property @@ -41,7 +43,7 @@ def get_useful_data(self) -> SupportsItems[str, Any]: ... class GenericCollection(Generic[_M]): - def __init__(self, session: 'Session', **kwargs: Any): + def __init__(self, session: Session, **kwargs: Any): self.session = session @property @@ -49,16 +51,16 @@ def model_class(self) -> type[_M]: raise NotImplementedError @cached_property - def primary_key(self) -> 'Column[str] | Column[UUID] | Column[int]': + def primary_key(self) -> Column[str] | Column[UUID] | Column[int]: return inspect(self.model_class).primary_key[0] - def query(self) -> 'Query[_M]': + def query(self) -> Query[_M]: return self.session.query(self.model_class) - def by_id(self, id: 'PKType') -> _M | None: + def by_id(self, id: PKType) -> _M | None: return self.query().filter(self.primary_key == id).first() - def by_ids(self, ids: 'Collection[PKType]') -> list[_M]: + def by_ids(self, ids: Collection[PKType]) -> list[_M]: # FIXME: This type error is a bug in the sqlalchemy-stubs # plugin, it might go away with SQLAlchemy 2.0, since # Column is being treated like a descriptor, even though @@ -83,8 +85,8 @@ def add(self, **kwargs: Any) -> _M: def add_by_form( self, - form: '_FormThatSupportsGetUsefulData', - properties: 'Iterable[str] | None' = None + form: _FormThatSupportsGetUsefulData, + properties: Iterable[str] | None = None ) -> _M: cls = self.model_class @@ -109,10 +111,10 @@ class SearcheableCollection(GenericCollection[_M]): @staticmethod def match_term( - column: 'Column[str] | Column[str | None]', + column: Column[str] | Column[str | None], language: str, term: str - ) -> 'ClauseElement': + ) -> ClauseElement: """ Usage: model.filter(match_term(model.col, 'german', 'my search term')) @@ -144,10 +146,10 @@ def cleanup(word: str, whitelist_chars: str = ',.-_') -> str: def filter_text_by_locale( self, - column: 'Column[str] | Column[str | None]', + column: Column[str] | Column[str | None], term: str, locale: str | None = None - ) -> 'ClauseElement': + ) -> ClauseElement: """ Returns an SqlAlchemy filter statement based on the search term. If no locale is provided, it will use english as language. @@ -182,17 +184,17 @@ def term(self) -> str: ... @property @abstractmethod - def term_filter_cols(self) -> dict[str, 'TextColumn']: ... + def term_filter_cols(self) -> dict[str, TextColumn]: ... else: @property - def term_filter_cols(self) -> dict[str, 'TextColumn']: + def term_filter_cols(self) -> dict[str, TextColumn]: """ Returns a dict of column names to search in with term. Must be attributes of self.model_class. """ raise NotImplementedError @property - def term_filter(self) -> 'Iterator[ClauseElement]': + def term_filter(self) -> Iterator[ClauseElement]: assert self.term_filter_cols term = self.__class__.term_to_tsquery_string(self.term) @@ -202,7 +204,7 @@ def term_filter(self) -> 'Iterator[ClauseElement]': for col in self.term_filter_cols ) - def query(self) -> 'Query[_M]': + def query(self) -> Query[_M]: if not self.term or not self.locale: return super().query() return super().query().filter(or_(*self.term_filter)) @@ -233,7 +235,7 @@ def __eq__(self, other: object) -> bool: """ raise NotImplementedError - def subset(self) -> 'Query[_M]': + def subset(self) -> Query[_M]: """ Returns an SQLAlchemy query containing all records that should be considered for pagination. @@ -241,7 +243,7 @@ def subset(self) -> 'Query[_M]': raise NotImplementedError @cached_property - def cached_subset(self) -> 'Query[_M]': + def cached_subset(self) -> Query[_M]: return self.subset() if TYPE_CHECKING: @@ -256,14 +258,14 @@ def page_index(self) -> int: """ Returns the current page index (starting at 0). """ raise NotImplementedError - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: """ Returns the page at the given index. A page here means an instance of the class inheriting from the ``Pagination`` base class. """ raise NotImplementedError - def transform_batch_query(self, query: 'Query[_M]') -> 'Query[_M]': + def transform_batch_query(self, query: Query[_M]) -> Query[_M]: """ Allows subclasses to transform the given query before it is used to retrieve the batch. This is a good place to add additional loading that should only apply to the batch (say joining other @@ -309,20 +311,20 @@ def name_of_view(self) -> str: return '' @property - def pages(self) -> 'Iterator[Self]': + def pages(self) -> Iterator[Self]: """ Yields all page objects of this Pagination. """ for page in range(self.pages_count): yield self.page_by_index(page) @property - def previous(self) -> 'Self | None': + def previous(self) -> Self | None: """ Returns the previous page or None. """ if self.page - 1 >= 0: return self.page_by_index(self.page - 1) return None @property - def next(self) -> 'Self | None': + def next(self) -> Self | None: """ Returns the next page or None. """ if self.page + 1 < self.pages_count: return self.page_by_index(self.page + 1) @@ -345,7 +347,7 @@ class RangedPagination(Generic[_M]): # may be clipped by using `limit_range`. range_limit = 5 - def subset(self) -> 'Query[_M]': + def subset(self) -> Query[_M]: """ Returns an SQLAlchemy query containing all records that should be considered for pagination. @@ -353,7 +355,7 @@ def subset(self) -> 'Query[_M]': raise NotImplementedError @cached_property - def cached_subset(self) -> 'Query[_M]': + def cached_subset(self) -> Query[_M]: return self.subset() @property @@ -361,7 +363,7 @@ def page_range(self) -> tuple[int, int]: """ Returns the current page range (starting at (0, 0)). """ raise NotImplementedError - def by_page_range(self, page_range: tuple[int, int]) -> 'Self': + def by_page_range(self, page_range: tuple[int, int]) -> Self: """ Returns an instance of the collection limited to the given page range. @@ -370,7 +372,7 @@ def by_page_range(self, page_range: tuple[int, int]) -> 'Self': def limit_range( self, - page_range: 'Sequence[int] | None', + page_range: Sequence[int] | None, direction: Literal['up', 'down'] ) -> tuple[int, int]: """ Limits the range to the range limit in the given direction. @@ -399,7 +401,7 @@ def limit_range( return (s, e) - def transform_batch_query(self, query: 'Query[_M]') -> 'Query[_M]': + def transform_batch_query(self, query: Query[_M]) -> Query[_M]: """ Allows subclasses to transform the given query before it is used to retrieve the batch. This is a good place to add additional loading that should only apply to the batch (say joining other @@ -439,7 +441,7 @@ def pages_count(self) -> int: return math.ceil(self.subset_count / self.batch_size) @property - def previous(self) -> 'Self | None': + def previous(self) -> Self | None: """ Returns the previous page or None. """ s, _e = self.page_range @@ -448,7 +450,7 @@ def previous(self) -> 'Self | None': return None @property - def next(self) -> 'Self | None': + def next(self) -> Self | None: """ Returns the next page range or None. """ _s, e = self.page_range diff --git a/src/onegov/core/converters.py b/src/onegov/core/converters.py index 7d5a726686..f67f9cbfca 100644 --- a/src/onegov/core/converters.py +++ b/src/onegov/core/converters.py @@ -1,4 +1,5 @@ """ Contains custom converters. """ +from __future__ import annotations import isodate import morepath @@ -64,7 +65,7 @@ def json_decode(s: str) -> dict[str, Any] | None: return json.loads(s) -def json_encode(d: 'Mapping[str, Any] | None') -> str: +def json_encode(d: Mapping[str, Any] | None) -> str: """ Encodes a dictionary to json. """ if not d: return '{}' @@ -100,7 +101,7 @@ def uuid_encode(uuid: UUID | str | None) -> str: @Framework.converter(type=UUID) -def get_default_uuid_converter() -> 'morepath.Converter[UUID]': +def get_default_uuid_converter() -> morepath.Converter[UUID]: return uuid_converter @@ -130,13 +131,13 @@ def bool_encode(d: bool | None) -> Literal['0', '1']: return d and '1' or '0' -bool_converter: 'morepath.Converter[bool]' = morepath.Converter( +bool_converter: morepath.Converter[bool] = morepath.Converter( decode=bool_decode, encode=bool_encode ) @Framework.converter(type=bool) -def get_default_bool_converter() -> 'morepath.Converter[bool]': +def get_default_bool_converter() -> morepath.Converter[bool]: return bool_converter @@ -162,7 +163,7 @@ def datetime_encode(d: datetime | None) -> str: @Framework.converter(type=datetime) -def get_default_datetime_converter() -> 'morepath.Converter[datetime]': +def get_default_datetime_converter() -> morepath.Converter[datetime]: return datetime_converter @@ -206,7 +207,7 @@ def move_direction_encode(d: str | MoveDirection | None) -> str: @Framework.converter(type=MoveDirection) def get_default_move_direction_converter( -) -> 'morepath.Converter[MoveDirection]': +) -> morepath.Converter[MoveDirection]: return move_direction_converter @@ -225,7 +226,7 @@ class LiteralConverter(LiteralConverterBase): def __init__(self, literal_type: Any, /) -> None: ... @overload - def __init__(self, *literals: 'LiteralString') -> None: ... + def __init__(self, *literals: LiteralString) -> None: ... def __init__(self, *literals: Any) -> None: if len(literals) == 1 and get_origin(literals[0]) is Literal: diff --git a/src/onegov/core/cronjobs.py b/src/onegov/core/cronjobs.py index b039a58428..9565bd7e95 100644 --- a/src/onegov/core/cronjobs.py +++ b/src/onegov/core/cronjobs.py @@ -50,6 +50,7 @@ def do_interesting_things(request): the cronjobs won't run. """ +from __future__ import annotations import sched import re @@ -95,7 +96,7 @@ def do_interesting_things(request): def parse_cron( value: str | int, type: Literal['hour', 'minute'] -) -> 'Iterable[int]': +) -> Iterable[int]: """ Minimal cron style interval parser. Currently only supports this:: * -> Run every hour, minute @@ -156,7 +157,7 @@ class Job(Generic[_JobFunc]): function: _JobFunc hour: int | str minute: int | str - timezone: 'TzInfo' + timezone: TzInfo offset: float once: bool url: str | None @@ -166,7 +167,7 @@ def __init__( function: _JobFunc, hour: int | str, minute: int | str, - timezone: 'TzInfoOrName', + timezone: TzInfoOrName, once: bool = False, url: str | None = None ): @@ -210,7 +211,7 @@ def title(self) -> str: return self.url.partition('://')[-1] - def runtimes(self, today: date) -> 'Iterator[datetime]': + def runtimes(self, today: date) -> Iterator[datetime]: """ Generates the runtimes of this job on the given day, excluding runtimes in the past. @@ -264,7 +265,7 @@ def id(self) -> str: """ return quote_plus(self.app.sign(self.name, 'cronjob-id')) - def as_request_call(self, request: 'CoreRequest') -> 'Job[Scheduled]': + def as_request_call(self, request: CoreRequest) -> Job[Scheduled]: """ Returns a new job which does the same as the old job, but it does so by calling an url which will execute the original job. @@ -327,8 +328,8 @@ class ApplicationBoundCronjobs(Thread): def __init__( self, - request: 'CoreRequest', - jobs: 'Iterable[Job[Executor]]' + request: CoreRequest, + jobs: Iterable[Job[Executor]] ): Thread.__init__(self, daemon=True) self.application_id = request.app.application_id @@ -358,14 +359,14 @@ def run_locked(self) -> None: self.scheduler.run() - def schedule(self, job: Job['Scheduled']) -> None: + def schedule(self, job: Job[Scheduled]) -> None: self.scheduler.enterabs( action=self.process_job, argument=(job, ), time=job.next_runtime().timestamp(), priority=0) - def process_job(self, job: Job['Scheduled']) -> None: + def process_job(self, job: Job[Scheduled]) -> None: log.info(f'Executing {job.title}') try: @@ -391,7 +392,7 @@ def process_job(self, job: Job['Scheduled']) -> None: @Framework.path(model=Job, path='/cronjobs/{id}') -def get_job(app: Framework, id: str) -> Job['Executor'] | None: +def get_job(app: Framework, id: str) -> Job[Executor] | None: """ The internal path to the cronjob. The id can't be guessed. """ # FIXME: This should really use a dynamic salt, but we will have to # be careful about race conditions between dispatch and @@ -408,17 +409,17 @@ def get_job(app: Framework, id: str) -> Job['Executor'] | None: @Framework.view(model=Job, permission=Public) -def run_job(self: Job['Executor'], request: 'CoreRequest') -> None: +def run_job(self: Job[Executor], request: CoreRequest) -> None: """ Executes the job. """ self.function(request) def register_cronjob( registry: object, - function: 'Executor', + function: Executor, hour: int | str, minute: int | str, - timezone: 'TzInfoOrName', + timezone: TzInfoOrName, once: bool = False ) -> None: diff --git a/src/onegov/core/crypto/__init__.py b/src/onegov/core/crypto/__init__.py index 2eb1d63f1f..5e18408623 100644 --- a/src/onegov/core/crypto/__init__.py +++ b/src/onegov/core/crypto/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.crypto.password import hash_password, verify_password from onegov.core.crypto.random import random_password from onegov.core.crypto.token import random_token diff --git a/src/onegov/core/crypto/password.py b/src/onegov/core/crypto/password.py index 7884aaece0..1a997b413d 100644 --- a/src/onegov/core/crypto/password.py +++ b/src/onegov/core/crypto/password.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from passlib.hash import bcrypt_sha256 diff --git a/src/onegov/core/crypto/random.py b/src/onegov/core/crypto/random.py index 025872387f..027d757d15 100644 --- a/src/onegov/core/crypto/random.py +++ b/src/onegov/core/crypto/random.py @@ -9,6 +9,7 @@ Author: Simon Sapin License: BSD """ +from __future__ import annotations import string import secrets @@ -115,7 +116,7 @@ class MarkovChain: The probabilities are built from the frequencies in the `sample` chain. Elements of the sample that are not a valid state are ignored. """ - def __init__(self, sample: 'Iterable[str]'): + def __init__(self, sample: Iterable[str]): counts = self.counts = defaultdict(lambda: defaultdict(int)) for current, next in pairwise(sample): counts[current][next] += 1 @@ -141,7 +142,7 @@ def next(self, state: str) -> str: rand -= weight raise AssertionError('unreachable') - def __iter__(self) -> 'Iterator[str]': + def __iter__(self) -> Iterator[str]: """ Return an infinite iterator of states. """ diff --git a/src/onegov/core/crypto/token.py b/src/onegov/core/crypto/token.py index fe231fafdd..e413e8ca33 100644 --- a/src/onegov/core/crypto/token.py +++ b/src/onegov/core/crypto/token.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import hashlib import os import secrets diff --git a/src/onegov/core/csv.py b/src/onegov/core/csv.py index c99d1dc5f0..43f9aa7a24 100644 --- a/src/onegov/core/csv.py +++ b/src/onegov/core/csv.py @@ -1,4 +1,5 @@ """ Offers tools to deal with csv (and xls, xlsx) files. """ +from __future__ import annotations import codecs @@ -125,14 +126,14 @@ class CSVFile(Generic[_RowT]): """ - rowtype: '_RowType[_RowT]' + rowtype: _RowType[_RowT] @overload def __init__( - self: 'DefaultCSVFile', + self: DefaultCSVFile, csvfile: IO[bytes], - expected_headers: 'Collection[str] | None ' = None, - dialect: 'type[Dialect] | Dialect | str | None' = None, + expected_headers: Collection[str] | None = None, + dialect: type[Dialect] | Dialect | str | None = None, encoding: str | None = None, rename_duplicate_column_names: bool = False, rowtype: None = None @@ -140,24 +141,24 @@ def __init__( @overload def __init__( - self: 'CSVFile[_RowT]', + self: CSVFile[_RowT], csvfile: IO[bytes], - expected_headers: 'Collection[str] | None ' = None, - dialect: 'type[Dialect] | Dialect | str | None' = None, + expected_headers: Collection[str] | None = None, + dialect: type[Dialect] | Dialect | str | None = None, encoding: str | None = None, rename_duplicate_column_names: bool = False, *, - rowtype: '_RowType[_RowT]' + rowtype: _RowType[_RowT] ): ... def __init__( self, csvfile: IO[bytes], - expected_headers: 'Collection[str] | None ' = None, - dialect: 'type[Dialect] | Dialect | str | None' = None, + expected_headers: Collection[str] | None = None, + dialect: type[Dialect] | Dialect | str | None = None, encoding: str | None = None, rename_duplicate_column_names: bool = False, - rowtype: '_RowType[_RowT] | None' = None + rowtype: _RowType[_RowT] | None = None ): # guess the encoding if not already provided @@ -215,11 +216,11 @@ def as_valid_identifier(value: str) -> str: result = result[1:] return result - def __iter__(self) -> 'Iterator[_RowT]': + def __iter__(self) -> Iterator[_RowT]: yield from self.lines @property - def lines(self) -> 'Iterator[_RowT]': + def lines(self) -> Iterator[_RowT]: self.csvfile.seek(0) encountered_empty_line = False @@ -266,7 +267,7 @@ def detect_encoding(csvfile: IO[bytes]) -> str: return 'cp1252' -def sniff_dialect(csv: str) -> type['Dialect']: +def sniff_dialect(csv: str) -> type[Dialect]: """ Takes the given csv string and returns the dialect or raises an error. Works just like Python's built in sniffer, just that it is a bit more conservative and doesn't just accept any kind of character as csv @@ -493,23 +494,23 @@ def estimate_width(text: str) -> float: @overload def get_keys_from_list_of_dicts( - rows: 'Iterable[dict[_SupportsRichComparisonT, Any]]', + rows: Iterable[dict[_SupportsRichComparisonT, Any]], key: None = None, reverse: bool = False -) -> tuple['_SupportsRichComparisonT', ...]: ... +) -> tuple[_SupportsRichComparisonT, ...]: ... @overload def get_keys_from_list_of_dicts( - rows: 'Iterable[dict[_T, Any]]', - key: 'KeyFunc[_T]', + rows: Iterable[dict[_T, Any]], + key: KeyFunc[_T], reverse: bool = False -) -> tuple['_T', ...]: ... +) -> tuple[_T, ...]: ... def get_keys_from_list_of_dicts( - rows: 'Iterable[dict[Any, Any]]', - key: 'KeyFunc[Any] | None' = None, + rows: Iterable[dict[Any, Any]], + key: KeyFunc[Any] | None = None, reverse: bool = False ) -> tuple[Any, ...]: """ Returns all keys of a list of dicts in an ordered tuple. @@ -540,9 +541,9 @@ def get_keys_from_list_of_dicts( def convert_list_of_dicts_to_csv( - rows: 'Iterable[dict[str, Any]]', - fields: 'Sequence[str] | None' = None, - key: 'KeyFunc[str] | None' = None, + rows: Iterable[dict[str, Any]], + fields: Sequence[str] | None = None, + key: KeyFunc[str] | None = None, reverse: bool = False ) -> str: """ Takes a list of dictionaries and returns a csv. @@ -578,9 +579,9 @@ def convert_list_of_dicts_to_csv( def convert_list_of_dicts_to_xlsx( - rows: 'Iterable[dict[str, Any]]', - fields: 'Sequence[str] | None' = None, - key: 'KeyFunc[str] | None' = None, + rows: Iterable[dict[str, Any]], + fields: Sequence[str] | None = None, + key: KeyFunc[str] | None = None, reverse: bool = False ) -> bytes: """ Takes a list of dictionaries and returns a xlsx. @@ -603,7 +604,7 @@ def convert_list_of_dicts_to_xlsx( # keep track of the maximum character width column_widths = [estimate_width(field) for field in fields_] - def values(row: dict[str, Any]) -> 'Iterator[str]': + def values(row: dict[str, Any]) -> Iterator[str]: for ix, field in enumerate(fields_): value = row.get(field, '') column_widths[ix] = max( @@ -631,9 +632,9 @@ def values(row: dict[str, Any]) -> 'Iterator[str]': def convert_list_of_list_of_dicts_to_xlsx( - row_list: 'Sequence[Iterable[dict[str, Any]]]', - titles_list: 'Sequence[str]', - key_list: 'Sequence[KeyFunc[str] | None] | None' = None, + row_list: Sequence[Iterable[dict[str, Any]]], + titles_list: Sequence[str], + key_list: Sequence[KeyFunc[str] | None] | None = None, reverse: bool = False ) -> bytes: """ @@ -663,7 +664,7 @@ def values( row: dict[str, Any], fields: tuple[str, ...] = fields, column_widths: list[float] = column_widths - ) -> 'Iterator[str]': + ) -> Iterator[str]: for ix, field in enumerate(fields): value = row.get(field, '') column_widths[ix] = max( @@ -689,7 +690,7 @@ def values( return file.read() -def normalize_sheet_titles(titles: 'Sequence[str]') -> list[str]: +def normalize_sheet_titles(titles: Sequence[str]) -> list[str]: """ Ensuring the title of the xlsx is valid. """ @@ -718,7 +719,7 @@ def valid_characters_or_raise(title: str) -> None: return titles -def avoid_duplicate_name(titles: 'Sequence[str]', title: str) -> str: +def avoid_duplicate_name(titles: Sequence[str], title: str) -> str: """ Naive check to see whether name already exists. If name does exist suggest a name using an incrementer @@ -749,11 +750,11 @@ def remove_first_word(title: str) -> str: return re.sub(r'^.*?-', '', title) -def has_duplicates(a_list: 'Sequence[Any]') -> bool: +def has_duplicates(a_list: Sequence[Any]) -> bool: return len(a_list) != len(set(a_list)) -def list_duplicates_index(a: 'Sequence[Any]') -> list[int]: +def list_duplicates_index(a: Sequence[Any]) -> list[int]: """ Returns a list of indexes of duplicates in a list. for example:: @@ -766,7 +767,7 @@ def list_duplicates_index(a: 'Sequence[Any]') -> list[int]: def parse_header( csv: str, - dialect: 'type[Dialect] | Dialect | str | None' = None, + dialect: type[Dialect] | Dialect | str | None = None, rename_duplicate_column_names: bool = False ) -> list[str]: """ Takes the first line of the given csv string and returns the headers. @@ -803,8 +804,8 @@ def parse_header( def match_headers( - headers: 'Collection[str]', - expected: 'Collection[str]' + headers: Collection[str], + expected: Collection[str] ) -> list[str]: """ Takes a list of normalized headers and matches them up against a list of expected headers. diff --git a/src/onegov/core/custom/__init__.py b/src/onegov/core/custom/__init__.py index 905ce664c3..70d07e12b7 100644 --- a/src/onegov/core/custom/__init__.py +++ b/src/onegov/core/custom/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.custom import custom_json as json __all__ = ('json', ) diff --git a/src/onegov/core/custom/custom_json.py b/src/onegov/core/custom/custom_json.py index 260130785b..0a616bd141 100644 --- a/src/onegov/core/custom/custom_json.py +++ b/src/onegov/core/custom/custom_json.py @@ -8,6 +8,7 @@ don't support decoding... """ +from __future__ import annotations import datetime import isodate @@ -72,8 +73,8 @@ def __init__( self, target: type[_T], prefix: str, - encode: 'Callable[[_T], str]', - decode: 'Callable[[str], _T]', + encode: Callable[[_T], str], + decode: Callable[[str], _T], ): super().__init__(target) @@ -123,15 +124,15 @@ def __init__(self, x, y): """ - def __init__(self, target: type[_T], keys: 'Iterable[str]'): + def __init__(self, target: type[_T], keys: Iterable[str]): super().__init__(target) self.keys = frozenset(keys) - def encode(self, obj: _T) -> 'JSONObject_ro': + def encode(self, obj: _T) -> JSONObject_ro: return {k: getattr(obj, k) for k in self.keys} - def decode(self, dictionary: 'JSONObject_ro') -> _T: + def decode(self, dictionary: JSONObject_ro) -> _T: return self.target(**dictionary) @@ -153,7 +154,7 @@ def __init__(self) -> None: self.known_key_lengths = set() @property - def registered(self) -> 'Iterator[AnySerializer[Any]]': + def registered(self) -> Iterator[AnySerializer[Any]]: return chain(self.by_prefix.values(), self.by_keys.values()) def register( @@ -173,7 +174,7 @@ def register( def serializer_for( self, value: object - ) -> 'AnySerializer[Any] | None': + ) -> AnySerializer[Any] | None: if isinstance(value, str): return self.serializer_for_string(value) @@ -211,11 +212,11 @@ def serializer_for_dict( def serializer_for_class( self, cls: type[_T] - ) -> 'AnySerializer[_T] | None': + ) -> AnySerializer[_T] | None: matches = (s for s in self.registered if issubclass(cls, s.target)) return next(matches, None) - def encode(self, value: object) -> 'JSON_ro': + def encode(self, value: object) -> JSON_ro: serializer = self.serializer_for(value.__class__) if serializer: @@ -292,13 +293,13 @@ def __init__(self, x, y): """ - serialized_keys: ClassVar['Collection[str]'] + serialized_keys: ClassVar[Collection[str]] @classmethod def serializers(cls) -> Serializers: return default_serializers # for testing - def __init_subclass__(cls, keys: 'Collection[str]', **kwargs: Any): + def __init_subclass__(cls, keys: Collection[str], **kwargs: Any): super().__init_subclass__(**kwargs) cls.serialized_keys = keys @@ -337,9 +338,9 @@ def loads(txt: str | bytes | bytearray | None, **extra: Any) -> Any: return {} -def dump(data: Any, fp: 'SupportsWrite[str]', **extra: Any) -> None: +def dump(data: Any, fp: SupportsWrite[str], **extra: Any) -> None: fp.write(dumps(data, **extra)) -def load(fp: 'SupportsRead[str | bytes]', **extra: Any) -> Any: +def load(fp: SupportsRead[str | bytes], **extra: Any) -> Any: return loads(fp.read(), **extra) diff --git a/src/onegov/core/datamanager.py b/src/onegov/core/datamanager.py index 2cf1ef1069..3cd5e6198d 100644 --- a/src/onegov/core/datamanager.py +++ b/src/onegov/core/datamanager.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os import tempfile import transaction @@ -33,21 +35,21 @@ def write_file( def sortKey(self) -> str: return 'files' - def commit(self, transaction: 'ITransaction') -> None: + def commit(self, transaction: ITransaction) -> None: with tempfile.NamedTemporaryFile(delete=False) as temp: self.tempfn = temp.name temp.write(self.data) - def abort(self, transaction: 'ITransaction') -> None: + def abort(self, transaction: ITransaction) -> None: pass - def tpc_vote(self, transaction: 'ITransaction') -> None: + def tpc_vote(self, transaction: ITransaction) -> None: if not os.path.exists(self.tempfn): raise ValueError(f'{self.tempfn} doesnt exist') if os.path.exists(self.path): raise ValueError('file already exists') - def tpc_abort(self, transaction: 'ITransaction') -> None: + def tpc_abort(self, transaction: ITransaction) -> None: # if another DataManager before us in the chain raises a retryable # error before we get to commit, we still have to execute tpc_abort # despite tempfn not existing yet. @@ -59,8 +61,8 @@ def tpc_abort(self, transaction: 'ITransaction') -> None: except OSError: pass - def tpc_begin(self, transaction: 'ITransaction') -> None: + def tpc_begin(self, transaction: ITransaction) -> None: pass - def tpc_finish(self, transaction: 'ITransaction') -> None: + def tpc_finish(self, transaction: ITransaction) -> None: safe_move(self.tempfn, self.path, tmp_dst=self.tmp_path) diff --git a/src/onegov/core/directives.py b/src/onegov/core/directives.py index c32f4fc7be..d4fc81a8aa 100644 --- a/src/onegov/core/directives.py +++ b/src/onegov/core/directives.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os.path from dectate import Action, Query @@ -53,10 +55,10 @@ def handle_form(self, request, form): def __init__( self, model: type | str, - form: 'type[Form] | Callable[[Any, _RequestT], type[Form]]', - render: 'Callable[[Any, _RequestT], Response] | str | None' = None, - template: 'StrOrBytesPath | None' = None, - load: 'Callable[[_RequestT], Any] | str | None' = None, + form: type[Form] | Callable[[Any, _RequestT], type[Form]], + render: Callable[[Any, _RequestT], Response] | str | None = None, + template: StrOrBytesPath | None = None, + load: Callable[[_RequestT], Any] | str | None = None, permission: object | str | None = None, internal: bool = False, **predicates: Any @@ -67,7 +69,7 @@ def __init__( def perform( self, - obj: 'Callable[[Any, _RequestT, Any], Any]', + obj: Callable[[Any, _RequestT, Any], Any], *args: Any, **kwargs: Any ) -> None: @@ -91,7 +93,7 @@ def perform( def fetch_form_class( - form_class: 'type[_FormT] | Callable[[Any, _RequestT], type[_FormT]]', + form_class: type[_FormT] | Callable[[Any, _RequestT], type[_FormT]], model: object, request: _RequestT ) -> type[_FormT]: @@ -110,7 +112,7 @@ def query_form_class( request: _RequestT, model: object, name: str | None = None -) -> 'type[Form] | None': +) -> type[Form] | None: """ Queries the app configuration for the form class associated with the given model and name. Take this configuration for example:: @@ -141,9 +143,9 @@ def query_form_class( def wrap_with_generic_form_handler( - obj: 'Callable[[_T, _RequestT, _FormT], Any]', - form_class: 'type[_FormT] | Callable[[_T, _RequestT], type[_FormT]]' -) -> 'Callable[[_T, _RequestT], Any]': + obj: Callable[[_T, _RequestT, _FormT], Any], + form_class: type[_FormT] | Callable[[_T, _RequestT], type[_FormT]] +) -> Callable[[_T, _RequestT], Any]: """ Wraps a view handler with generic form handling. This includes instantiating the form with translations/csrf protection @@ -195,7 +197,7 @@ def identifier(self, **kw: Any) -> int: def perform( # type:ignore[override] self, - func: 'Callable[[CoreRequest], Any]', + func: Callable[[CoreRequest], Any], cronjob_registry: Bunch ) -> None: from onegov.core.cronjobs import register_cronjob @@ -228,7 +230,7 @@ def identifier( # type:ignore[override] def perform( # type:ignore[override] self, - func: 'Callable[..., Any]', + func: Callable[..., Any], staticdirectory_registry: Bunch ) -> None: @@ -253,7 +255,7 @@ def __init__(self) -> None: def get_variables( self, - request: 'CoreRequest', + request: CoreRequest, base: dict[str, Any] | None = None ) -> dict[str, Any]: base = base or {} @@ -300,7 +302,7 @@ def identifier( # type:ignore[override] def perform( # type:ignore[override] self, - func: 'Callable[[CoreRequest], dict[str, Any]]', + func: Callable[[CoreRequest], dict[str, Any]], templatevariables_registry: TemplateVariablesRegistry ) -> None: templatevariables_registry.callbacks.append(func) diff --git a/src/onegov/core/elements.py b/src/onegov/core/elements.py index 37e6cf6145..b8e2019e63 100644 --- a/src/onegov/core/elements.py +++ b/src/onegov/core/elements.py @@ -13,6 +13,7 @@ This module should eventually replace the elements.py module. """ +from __future__ import annotations from onegov.core.templates import render_macro @@ -60,7 +61,7 @@ def __init__( self, text: str | None = None, attrs: dict[str, Any] | None = None, - traits: 'Iterable[Trait] | Trait' = (), + traits: Iterable[Trait] | Trait = (), **props: Any ): self.text = text @@ -104,9 +105,9 @@ def __getattr__(self, name: str) -> Any: def __call__( self, - layout: 'ChameleonLayout', - extra_classes: 'Iterable[str] | None' = None - ) -> 'Markup': + layout: ChameleonLayout, + extra_classes: Iterable[str] | None = None + ) -> Markup: assert self.id is not None @@ -161,7 +162,7 @@ def __init__( text: str | None, url: str = '#', attrs: dict[str, Any] | None = None, - traits: 'Iterable[Trait] | Trait' = (), + traits: Iterable[Trait] | Trait = (), **props: Any ): # this is the only exception we permit where we don't use a trait @@ -220,10 +221,10 @@ class LinkGroup(AccessMixin): def __init__( self, title: str, - links: 'Sequence[Link]', + links: Sequence[Link], model: Any | None = None, right_side: bool = True, - classes: 'Collection[str] | None' = None, + classes: Collection[str] | None = None, attributes: dict[str, Any] | None = None ): self.title = title @@ -239,7 +240,7 @@ class Trait: __slots__ = ('apply', ) - apply: 'Callable[[dict[str, Any]], dict[str, Any]]' + apply: Callable[[dict[str, Any]], dict[str, Any]] def __call__( self, diff --git a/src/onegov/core/errors.py b/src/onegov/core/errors.py index 1b92784eca..d00659e685 100644 --- a/src/onegov/core/errors.py +++ b/src/onegov/core/errors.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import TYPE_CHECKING if TYPE_CHECKING: from collections.abc import Mapping, Sequence @@ -8,12 +10,12 @@ class CSVError(Exception): class MissingColumnsError(CSVError): - def __init__(self, columns: 'Sequence[str]'): + def __init__(self, columns: Sequence[str]): self.columns = columns class AmbiguousColumnsError(CSVError): - def __init__(self, columns: 'Mapping[str, Sequence[str]]'): + def __init__(self, columns: Mapping[str, Sequence[str]]): self.columns = columns diff --git a/src/onegov/core/filestorage.py b/src/onegov/core/filestorage.py index c282f98127..368c0215de 100644 --- a/src/onegov/core/filestorage.py +++ b/src/onegov/core/filestorage.py @@ -6,6 +6,7 @@ See :attr:`onegov.core.framework.Framework.filestorage` for more information. """ +from __future__ import annotations from fs.errors import IllegalBackReference from onegov.core.framework import Framework @@ -67,7 +68,7 @@ def get_filestorage_file( @Framework.view(model=FilestorageFile, render=render_file, permission=Public) def view_filestorage_file( self: FilestorageFile, - request: 'CoreRequest' + request: CoreRequest ) -> str: """ Renders the given filestorage file in the browser. """ return getattr(request.app, self.storage).getsyspath(self.path) @@ -75,7 +76,7 @@ def view_filestorage_file( @Framework.view( model=FilestorageFile, request_method='DELETE', permission=Private) -def delete_static_file(self: FilestorageFile, request: 'CoreRequest') -> None: +def delete_static_file(self: FilestorageFile, request: CoreRequest) -> None: """ Deletes the given filestorage file. By default the permission is ``Private``. An application using the framework can override this though. diff --git a/src/onegov/core/filters.py b/src/onegov/core/filters.py index 386a21fea0..08d4fc5677 100644 --- a/src/onegov/core/filters.py +++ b/src/onegov/core/filters.py @@ -1,4 +1,6 @@ """ Extra webasset filters. """ +from __future__ import annotations + import os import rcssmin # type:ignore[import-untyped] @@ -12,7 +14,7 @@ from typing import Any, IO -class JsxFilter(BabelJSX): +class JsxFilter(BabelJSX): # type:ignore[misc] """ DukPy is a simple javascript interpreter for Python built on top of duktape engine without any external dependency. @@ -50,7 +52,7 @@ def setup(self) -> None: register_filter(JsxFilter) -class DataUriFilter(CSSDataUri): +class DataUriFilter(CSSDataUri): # type:ignore[misc] """ Overrides the default datauri filter to work around this issue: https://github.com/miracle2k/webassets/issues/387 @@ -81,7 +83,7 @@ def output_url(self) -> str: register_filter(DataUriFilter) -class RCSSMinFilter(Filter): +class RCSSMinFilter(Filter): # type:ignore[misc] """ Adds the rcssmin filter (not yet included in webassets) """ name = 'custom-rcssmin' diff --git a/src/onegov/core/framework.py b/src/onegov/core/framework.py index 34af9326a3..6fe8257b9f 100644 --- a/src/onegov/core/framework.py +++ b/src/onegov/core/framework.py @@ -15,6 +15,7 @@ class MyApplication(Framework): pass """ +from __future__ import annotations import dectate import hashlib @@ -106,7 +107,7 @@ class Framework( ): """ Baseclass for Morepath OneGov applications. """ - request_class: type['Request'] = CoreRequest + request_class: type[Request] = CoreRequest #: holds the database connection string, *if* there is a database connected dsn: str | None = None @@ -153,7 +154,7 @@ def __call__( ) -> Iterable[bytes]: ... @morepath.reify # type:ignore[no-redef] - def __call__(self) -> 'WSGIApplication': + def __call__(self) -> WSGIApplication: """ Intercept all wsgi calls so we can attach debug tools. """ fn: WSGIApplication = super().__call__ @@ -172,12 +173,12 @@ def __call__(self) -> 'WSGIApplication': return fn - def with_query_report(self, fn: 'Callable[_P, _T]') -> 'Callable[_P, _T]': + def with_query_report(self, fn: Callable[_P, _T]) -> Callable[_P, _T]: @wraps(fn) def with_query_report_wrapper( - *args: '_P.args', - **kwargs: '_P.kwargs' + *args: _P.args, + **kwargs: _P.kwargs ) -> _T: assert isinstance(self.sql_query_report, str) @@ -186,12 +187,12 @@ def with_query_report_wrapper( return with_query_report_wrapper - def with_profiler(self, fn: 'Callable[_P, _T]') -> 'Callable[_P, _T]': + def with_profiler(self, fn: Callable[_P, _T]) -> Callable[_P, _T]: @wraps(fn) def with_profiler_wrapper( - *args: '_P.args', - **kwargs: '_P.kwargs' + *args: _P.args, + **kwargs: _P.kwargs ) -> _T: filename = '{:%Y-%m-%d %H:%M:%S}.profile'.format(datetime.now()) @@ -200,12 +201,12 @@ def with_profiler_wrapper( return with_profiler_wrapper - def with_request_cache(self, fn: 'Callable[_P, _T]') -> 'Callable[_P, _T]': + def with_request_cache(self, fn: Callable[_P, _T]) -> Callable[_P, _T]: @wraps(fn) def with_request_cache_wrapper( - *args: '_P.args', - **kwargs: '_P.kwargs' + *args: _P.args, + **kwargs: _P.kwargs ) -> _T: self.clear_request_cache() return fn(*args, **kwargs) @@ -214,13 +215,13 @@ def with_request_cache_wrapper( def with_print_exceptions( self, - fn: 'Callable[_P, _T]' - ) -> 'Callable[_P, _T]': + fn: Callable[_P, _T] + ) -> Callable[_P, _T]: @wraps(fn) def with_print_exceptions_wrapper( - *args: '_P.args', - **kwargs: '_P.kwargs' + *args: _P.args, + **kwargs: _P.kwargs ) -> _T: try: return fn(*args, **kwargs) @@ -269,7 +270,7 @@ def modules(self) -> utils.Bunch: ) @property - def metadata(self) -> 'Metadata': + def metadata(self) -> Metadata: return self.modules.metadata.Metadata(self) @property @@ -291,9 +292,9 @@ def has_filestorage(self) -> bool: def handle_exception( self, exception: BaseException, - environ: 'WSGIEnvironment', - start_response: 'StartResponse' - ) -> 'Iterable[bytes]': + environ: WSGIEnvironment, + start_response: StartResponse + ) -> Iterable[bytes]: """ Stops database connection errors from bubbling all the way up to our exception handling services (sentry.io). @@ -713,7 +714,7 @@ def cache(self) -> cache.RedisCacheRegion: return self.get_cache('short-term', expiration_time=3600) @property - def settings(self) -> 'SettingRegistry': + def settings(self) -> SettingRegistry: return self.config.setting_registry @property @@ -787,7 +788,7 @@ def permission_by_view( self, model: type[object] | object, view_name: str | None = None - ) -> type['Intent']: + ) -> type[Intent]: """ Returns the permission required for the given model and view_name. The model may be an instance or a class. @@ -815,19 +816,19 @@ def permission_by_view( return action.permission @cached_property - def session(self) -> 'Callable[[], Session]': + def session(self) -> Callable[[], Session]: """ Alias for self.session_manager.session. """ return self.session_manager.session def send_marketing_email( self, - reply_to: 'Address | str | None' = None, - receivers: 'SequenceOrScalar[Address | str]' = (), - cc: 'SequenceOrScalar[Address | str]' = (), - bcc: 'SequenceOrScalar[Address | str]' = (), + reply_to: Address | str | None = None, + receivers: SequenceOrScalar[Address | str] = (), + cc: SequenceOrScalar[Address | str] = (), + bcc: SequenceOrScalar[Address | str] = (), subject: str | None = None, content: str | None = None, - attachments: 'Iterable[Attachment | StrPath]' = (), + attachments: Iterable[Attachment | StrPath] = (), headers: dict[str, str] | None = None, plaintext: str | None = None ) -> None: @@ -862,7 +863,7 @@ def send_marketing_email( def send_marketing_email_batch( self, - prepared_emails: 'Iterable[EmailJsonDict]' + prepared_emails: Iterable[EmailJsonDict] ) -> None: """ Sends an e-mail batch categorised as marketing. @@ -892,13 +893,13 @@ def send_marketing_email_batch( def send_transactional_email( self, - reply_to: 'Address | str | None' = None, - receivers: 'SequenceOrScalar[Address | str]' = (), - cc: 'SequenceOrScalar[Address | str]' = (), - bcc: 'SequenceOrScalar[Address | str]' = (), + reply_to: Address | str | None = None, + receivers: SequenceOrScalar[Address | str] = (), + cc: SequenceOrScalar[Address | str] = (), + bcc: SequenceOrScalar[Address | str] = (), subject: str | None = None, content: str | None = None, - attachments: 'Iterable[Attachment | StrPath]' = (), + attachments: Iterable[Attachment | StrPath] = (), headers: dict[str, str] | None = None, plaintext: str | None = None ) -> None: @@ -928,7 +929,7 @@ def send_transactional_email( def send_transactional_email_batch( self, - prepared_emails: 'Iterable[EmailJsonDict]' + prepared_emails: Iterable[EmailJsonDict] ) -> None: """ Sends an e-mail categorised as transactional. @@ -953,17 +954,17 @@ def send_transactional_email_batch( def prepare_email( self, - reply_to: 'Address | str | None' = None, + reply_to: Address | str | None = None, category: Literal['marketing', 'transactional'] = 'marketing', - receivers: 'SequenceOrScalar[Address | str]' = (), - cc: 'SequenceOrScalar[Address | str]' = (), - bcc: 'SequenceOrScalar[Address | str]' = (), + receivers: SequenceOrScalar[Address | str] = (), + cc: SequenceOrScalar[Address | str] = (), + bcc: SequenceOrScalar[Address | str] = (), subject: str | None = None, content: str | None = None, - attachments: 'Iterable[Attachment | StrPath]' = (), + attachments: Iterable[Attachment | StrPath] = (), headers: dict[str, str] | None = None, plaintext: str | None = None - ) -> 'EmailJsonDict': + ) -> EmailJsonDict: """ Common path for batch and single mail sending. Use this the same way you would use send_email then pass the prepared emails in a list or another iterable to the batch send method. @@ -1007,14 +1008,14 @@ def prepare_email( def send_email( self, - reply_to: 'Address | str | None' = None, + reply_to: Address | str | None = None, category: Literal['marketing', 'transactional'] = 'marketing', - receivers: 'SequenceOrScalar[Address | str]' = (), - cc: 'SequenceOrScalar[Address | str]' = (), - bcc: 'SequenceOrScalar[Address | str]' = (), + receivers: SequenceOrScalar[Address | str] = (), + cc: SequenceOrScalar[Address | str] = (), + bcc: SequenceOrScalar[Address | str] = (), subject: str | None = None, content: str | None = None, - attachments: 'Iterable[Attachment | StrPath]' = (), + attachments: Iterable[Attachment | StrPath] = (), headers: dict[str, str] | None = None, plaintext: str | None = None ) -> None: @@ -1070,7 +1071,7 @@ def send_email( def send_email_batch( self, - prepared_emails: 'Iterable[EmailJsonDict]', + prepared_emails: Iterable[EmailJsonDict], category: Literal['marketing', 'transactional'] = 'marketing' ) -> None: """ Sends an e-mail batch. @@ -1175,7 +1176,7 @@ def can_deliver_sms(self) -> bool: def send_sms( self, - receivers: 'SequenceOrScalar[str]', + receivers: SequenceOrScalar[str], content: str | bytes ) -> None: """ Sends an SMS by writing a file to the `sms_directory` of the @@ -1330,7 +1331,7 @@ def application_bound_identity( ) @property - def filestorage(self) -> 'SubFS[FS] | None': + def filestorage(self) -> SubFS[FS] | None: """ Returns a filestorage object bound to the current application. Based on this nifty module: @@ -1384,7 +1385,7 @@ def filestorage(self) -> 'SubFS[FS] | None': return utils.makeopendir(self._global_file_storage, self.schema) @property - def themestorage(self) -> 'SubFS[FS] | None': + def themestorage(self) -> SubFS[FS] | None: """ Returns a storage object meant for themes, shared by all applications. @@ -1403,7 +1404,7 @@ def theme_options(self) -> dict[str, Any]: return {} @cached_property - def translations(self) -> dict[str, 'GNUTranslations']: + def translations(self) -> dict[str, GNUTranslations]: """ Returns all available translations keyed by language. """ try: @@ -1417,7 +1418,7 @@ def translations(self) -> dict[str, 'GNUTranslations']: return {} @cached_property - def chameleon_translations(self) -> dict[str, '_ChameleonTranslate']: + def chameleon_translations(self) -> dict[str, _ChameleonTranslate]: """ Returns all available translations for chameleon. """ return self.modules.i18n.wrap_translations_for_chameleon( self.translations @@ -1526,9 +1527,9 @@ def get_jsx_filter() -> str: @Framework.tween_factory(over=webassets_injector_tween) def fix_webassets_url_factory( app: Framework, - handler: 'Callable[[CoreRequest], Response]' -) -> 'Callable[[CoreRequest], Response]': - def fix_webassets_url(request: CoreRequest) -> 'Response': + handler: Callable[[CoreRequest], Response] +) -> Callable[[CoreRequest], Response]: + def fix_webassets_url(request: CoreRequest) -> Response: """ more.webassets is not aware of our virtual hosting situation introduced by onegov.server - therefore it doesn't produce the right urls. This is something Morepath would have to fix. @@ -1622,13 +1623,13 @@ def default_content_security_policy() -> ContentSecurityPolicy: @Framework.setting(section='content_security_policy', name='apply_policy') def default_policy_apply_factory( -) -> 'Callable[[ContentSecurityPolicy, CoreRequest, Response], None]': +) -> Callable[[ContentSecurityPolicy, CoreRequest, Response], None]: """ Adds the content security policy report settings from the yaml. """ def apply_policy( policy: ContentSecurityPolicy, request: CoreRequest, - response: 'Response' + response: Response ) -> None: if not request.app.content_security_policy_enabled: @@ -1653,10 +1654,10 @@ def apply_policy( @Framework.tween_factory(over=transaction_tween_factory) def http_conflict_tween_factory( app: Framework, - handler: 'Callable[[CoreRequest], Response]' -) -> 'Callable[[CoreRequest], Response]': + handler: Callable[[CoreRequest], Response] +) -> Callable[[CoreRequest], Response]: - def http_conflict_tween(request: CoreRequest) -> 'Response': + def http_conflict_tween(request: CoreRequest) -> Response: """ When two transactions conflict, postgres raises an error which more.transaction handles by retrying the transaction for the configured amount of time. See :func:`get_retry_attempts`. @@ -1686,10 +1687,10 @@ def http_conflict_tween(request: CoreRequest) -> 'Response': @Framework.tween_factory(over=transaction_tween_factory) def activate_session_manager_factory( app: Framework, - handler: 'Callable[[CoreRequest], Response]' -) -> 'Callable[[CoreRequest], Response]': + handler: Callable[[CoreRequest], Response] +) -> Callable[[CoreRequest], Response]: """ Activate the session manager before each transaction. """ - def activate_session_manager(request: CoreRequest) -> 'Response': + def activate_session_manager(request: CoreRequest) -> Response: if app.has_database_connection: request.app.session_manager.activate() @@ -1701,15 +1702,15 @@ def activate_session_manager(request: CoreRequest) -> 'Response': @Framework.tween_factory(over=transaction_tween_factory) def close_session_after_request_factory( app: Framework, - handler: 'Callable[[CoreRequest], Response]' -) -> 'Callable[[CoreRequest], Response]': + handler: Callable[[CoreRequest], Response] +) -> Callable[[CoreRequest], Response]: """ Closes the session after each request. This frees up connections that are unused, without costing us any request performance from what I can measure. """ - def close_session_after_request(request: CoreRequest) -> 'Response': + def close_session_after_request(request: CoreRequest) -> Response: try: return handler(request) finally: @@ -1722,9 +1723,9 @@ def close_session_after_request(request: CoreRequest) -> 'Response': @Framework.tween_factory(under=http_conflict_tween_factory) def current_language_tween_factory( app: Framework, - handler: 'Callable[[CoreRequest], Response]' -) -> 'Callable[[CoreRequest], Response]': - def current_language_tween(request: CoreRequest) -> 'Response': + handler: Callable[[CoreRequest], Response] +) -> Callable[[CoreRequest], Response]: + def current_language_tween(request: CoreRequest) -> Response: """ Set the current language on the session manager for each request, for translatable database columns. @@ -1744,8 +1745,8 @@ def current_language_tween(request: CoreRequest) -> 'Response': @Framework.tween_factory(under=current_language_tween_factory) def spawn_cronjob_thread_tween_factory( app: Framework, - handler: 'Callable[[CoreRequest], Response]' -) -> 'Callable[[CoreRequest], Response]': + handler: Callable[[CoreRequest], Response] +) -> Callable[[CoreRequest], Response]: from onegov.core.cronjobs import ApplicationBoundCronjobs registry = app.config.cronjob_registry @@ -1756,7 +1757,7 @@ def spawn_cronjob_thread_tween_factory( if not app.settings.cronjobs.enabled: return handler - def spawn_cronjob_thread_tween(request: CoreRequest) -> 'Response': + def spawn_cronjob_thread_tween(request: CoreRequest) -> Response: if app.application_id not in registry.cronjob_threads: thread = ApplicationBoundCronjobs( request, registry.cronjobs.values() diff --git a/src/onegov/core/html.py b/src/onegov/core/html.py index af7f08d392..8009935225 100644 --- a/src/onegov/core/html.py +++ b/src/onegov/core/html.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re from bleach.sanitizer import Cleaner diff --git a/src/onegov/core/html_diff.py b/src/onegov/core/html_diff.py index 6c2b4ab392..a17d8d6294 100644 --- a/src/onegov/core/html_diff.py +++ b/src/onegov/core/html_diff.py @@ -22,6 +22,8 @@ :copyright: (c) 2011 by Armin Ronacher :license: BSD """ +from __future__ import annotations + import re from contextlib import contextmanager from difflib import SequenceMatcher @@ -90,9 +92,9 @@ class StreamDiffer: so the tags the `StreamDiffer` adds are also unnamespaced. """ - _old: list['StreamEvent'] - _new: list['StreamEvent'] - _result: list['StreamEvent'] + _old: list[StreamEvent] + _new: list[StreamEvent] + _result: list[StreamEvent] _stack: list[str] _context: str | None @@ -105,7 +107,7 @@ def __init__(self, old_stream: ET, new_stream: ET): self._context = None @contextmanager - def context(self, kind: str | None) -> 'Iterator[None]': + def context(self, kind: str | None) -> Iterator[None]: old_context = self._context self._context = kind try: @@ -120,9 +122,9 @@ def inject_class(self, attrs: Attrs, classname: str) -> Attrs: def append( self, - type: 'StreamEventKind', + type: StreamEventKind, data: Any, - pos: 'Position' + pos: Position ) -> None: self._result.append((type, data, pos)) @@ -136,7 +138,7 @@ def cut_leading_space(self, s: str) -> tuple[str, str]: return '', s return match.group(), s[match.end():] - def mark_text(self, pos: 'Position', text: str, tag: str) -> None: + def mark_text(self, pos: Position, text: str, tag: str) -> None: ws, text = self.cut_leading_space(text) tag = QName(tag) if ws: @@ -145,7 +147,7 @@ def mark_text(self, pos: 'Position', text: str, tag: str) -> None: self.append(TEXT, text, pos) self.append(END, tag, pos) - def diff_text(self, pos: 'Position', old_text: str, new_text: str) -> None: + def diff_text(self, pos: Position, old_text: str, new_text: str) -> None: old = self.text_split(old_text) new = self.text_split(new_text) matcher = SequenceMatcher(None, old, new) @@ -253,7 +255,7 @@ def enter(self, pos: Any, tag: Any, attrs: dict[str, Any]) -> None: def enter_mark_replaced( self, - pos: 'Position', + pos: Position, tag: str, attrs: Attrs ) -> None: @@ -261,7 +263,7 @@ def enter_mark_replaced( self._stack.append(tag) self.append(START, (tag, attrs), pos) - def leave(self, pos: 'Position', tag: str) -> bool: + def leave(self, pos: Position, tag: str) -> bool: if not self._stack: return False if tag == self._stack[-1]: @@ -277,7 +279,7 @@ def leave_all(self) -> None: self.append(END, tag, last_pos) del self._stack[:] - def block_process(self, events: list['StreamEvent']) -> None: + def block_process(self, events: list[StreamEvent]) -> None: for event in events: type, data, pos = event if type == START: diff --git a/src/onegov/core/i18n/__init__.py b/src/onegov/core/i18n/__init__.py index ef9de14603..fefb9199f8 100644 --- a/src/onegov/core/i18n/__init__.py +++ b/src/onegov/core/i18n/__init__.py @@ -31,6 +31,7 @@ def get_i18n_default_locale(): return 'en' """ +from __future__ import annotations import gettext import glob @@ -101,7 +102,7 @@ def get_i18n_default_locale() -> None: @Framework.setting(section='i18n', name='locale_negotiator') -def get_i18n_locale_negotiatior() -> 'LocaleNegotiator': +def get_i18n_locale_negotiatior() -> LocaleNegotiator: """ Returns the language negotiator, which is a function that takes the current request as well as a list of available languages and returns the angauge that should be used based on that information. @@ -111,8 +112,8 @@ def get_i18n_locale_negotiatior() -> 'LocaleNegotiator': def default_locale_negotiator( - locales: 'Collection[str]', - request: 'CoreRequest' + locales: Collection[str], + request: CoreRequest ) -> str | None: """ The default locale negotiator. @@ -139,7 +140,7 @@ def default_locale_negotiator( return None -def pofiles(localedir: 'StrPath') -> 'Iterator[tuple[str, str]]': +def pofiles(localedir: StrPath) -> Iterator[tuple[str, str]]: """ Takes the given directory and yields the language and the path of all pofiles found under ``*/LC_MESSAGES/*.po``. @@ -175,7 +176,7 @@ def compile_translation(pofile_path: str) -> gettext.GNUTranslations: def get_translations( - localedirs: 'Iterable[StrPath]' + localedirs: Iterable[StrPath] ) -> dict[str, gettext.GNUTranslations]: """ Takes the given gettext locale directories and loads the po files found. The first found po file is assumed to be the main @@ -223,7 +224,7 @@ def get_translations( def wrap_translations_for_chameleon( translations: dict[str, gettext.GNUTranslations] -) -> dict[str, '_ChameleonTranslate']: +) -> dict[str, _ChameleonTranslate]: """ Takes the given translations and wraps them for use with Chameleon. """ return { @@ -234,7 +235,7 @@ def wrap_translations_for_chameleon( def translation_chain( translation: gettext.GNUTranslations -) -> 'Iterator[gettext.GNUTranslations]': +) -> Iterator[gettext.GNUTranslations]: """ Yields the translation chain with a generator. """ stack = [translation] @@ -266,7 +267,7 @@ class TranslationBoundMeta(meta_class): # type:ignore def get_translations( self, - form: 'Form' + form: Form ) -> gettext.GNUTranslations | None: nonlocal translations @@ -314,9 +315,9 @@ def get_translations( def render_field( self, - field: 'Field', + field: Field, render_kw: dict[str, Any] - ) -> 'Markup': + ) -> Markup: """ Wtforms does not actually translate labels, it simply leaves the translations string be. If those translation strings hit our templates directly, they will then be picked up by our template @@ -357,7 +358,7 @@ class TranslationBoundForm(form_class): # type:ignore def merge( - translations: 'Sequence[gettext.GNUTranslations]' + translations: Sequence[gettext.GNUTranslations] ) -> gettext.GNUTranslations: """ Takes the given translations (a list) and merges them into each other. The translations at the end of the list are overwritten @@ -412,7 +413,7 @@ def for_path( cls, app: Framework, locale: str - ) -> 'Self | None': + ) -> Self | None: if locale in app.locales: return cls(locale) @@ -421,10 +422,10 @@ def for_path( def __init__(self, locale: str): self.locale = locale - def link(self, request: 'CoreRequest', to: str) -> str: + def link(self, request: CoreRequest, to: str) -> str: return request.return_to(request.link(self), to) - def redirect(self, request: 'CoreRequest') -> 'Response': + def redirect(self, request: CoreRequest) -> Response: response = request.redirect('') # use return-to response.set_cookie( 'locale', diff --git a/src/onegov/core/i18n/translation_string.py b/src/onegov/core/i18n/translation_string.py index fe20864db9..abd87bc392 100644 --- a/src/onegov/core/i18n/translation_string.py +++ b/src/onegov/core/i18n/translation_string.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from markupsafe import escape from markupsafe import Markup from translationstring import TranslationString @@ -24,7 +26,7 @@ def __call__( context: str | None = None, *, markup: bool = False, - ) -> 'TranslationMarkup': ... + ) -> TranslationMarkup: ... @overload def __call__( @@ -35,7 +37,7 @@ def __call__( context: str | None = None, *, markup: Literal[True], - ) -> 'TranslationMarkup': ... + ) -> TranslationMarkup: ... @overload def __call__( @@ -62,12 +64,12 @@ class TranslationMarkup(TranslationString): def __new__( cls, - msgid: 'str | HasHTML | Self', + msgid: str | HasHTML | Self, domain: str | None = None, - default: 'str | HasHTML | None' = None, + default: str | HasHTML | None = None, mapping: dict[str, Any] | None = None, context: str | None = None, - ) -> 'Self': + ) -> Self: _default: Markup | None if default is None: @@ -109,7 +111,7 @@ def __new__( instance.mapping = _mapping return instance - def __mod__(self, options: Any) -> 'Self': + def __mod__(self, options: Any) -> Self: if isinstance(options, dict): # Ensure everything is escaped before it gets replaced options = {k: escape(v) for k, v in options.items()} @@ -123,7 +125,7 @@ def interpolate(self, translated: str | None = None) -> Markup: ) @classmethod - def escape(cls, s: object) -> 'Self': + def escape(cls, s: object) -> Self: if isinstance(s, cls): return s elif isinstance(s, TranslationString): @@ -144,25 +146,25 @@ def __html__(self) -> Markup: return self.interpolate() -def TranslationStringFactory(factory_domain: str) -> 'TStrCallable': # noqa: N802 +def TranslationStringFactory(factory_domain: str) -> TStrCallable: # noqa: N802 """ Creates a TranslationMarkup for Markup and a TranslationString otherwise. """ @overload def create( - msgid: 'HasHTML', + msgid: HasHTML, mapping: dict[str, Any] | None = None, - default: 'str | HasHTML | None' = None, + default: str | HasHTML | None = None, context: str | None = None, *, markup: bool = False, ) -> TranslationMarkup: ... @overload def create( - msgid: 'str | HasHTML', + msgid: str | HasHTML, mapping: dict[str, Any] | None = None, - default: 'str | HasHTML | None' = None, + default: str | HasHTML | None = None, context: str | None = None, *, markup: Literal[True], @@ -178,9 +180,9 @@ def create( ) -> TranslationString: ... def create( - msgid: 'str | HasHTML', + msgid: str | HasHTML, mapping: dict[str, Any] | None = None, - default: 'str | HasHTML | None' = None, + default: str | HasHTML | None = None, context: str | None = None, *, markup: bool = False, diff --git a/src/onegov/core/layout.py b/src/onegov/core/layout.py index b44fadae7c..b60a906e8e 100644 --- a/src/onegov/core/layout.py +++ b/src/onegov/core/layout.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import arrow import babel.dates import babel.numbers @@ -80,7 +82,7 @@ class Layout: custom_body_attributes: dict[str, Any] custom_html_attributes: dict[str, Any] - def __init__(self, model: Any, request: 'CoreRequest'): + def __init__(self, model: Any, request: CoreRequest): self.model = model self.request = request self.custom_body_attributes = {} @@ -93,25 +95,25 @@ def __init__(self, model: Any, request: 'CoreRequest'): ] = request.app.sentry_dsn @cached_property - def app(self) -> 'Framework': + def app(self) -> Framework: """ Returns the application behind the request. """ return self.request.app @overload def batched( self, - iterable: 'Iterable[_T]', + iterable: Iterable[_T], batch_size: int, - container_factory: 'type[tuple]' = ... # type:ignore[type-arg] - ) -> 'Iterator[tuple[_T, ...]]': ... + container_factory: type[tuple] = ... # type:ignore[type-arg] + ) -> Iterator[tuple[_T, ...]]: ... @overload def batched( self, - iterable: 'Iterable[_T]', + iterable: Iterable[_T], batch_size: int, - container_factory: 'type[list]' # type:ignore[type-arg] - ) -> 'Iterator[list[_T]]': ... + container_factory: type[list] # type:ignore[type-arg] + ) -> Iterator[list[_T]]: ... # NOTE: If there were higher order TypeVars, we could properly infer # the type of the Container, for now we just add overloads for @@ -119,17 +121,17 @@ def batched( @overload def batched( self, - iterable: 'Iterable[_T]', + iterable: Iterable[_T], batch_size: int, - container_factory: 'Callable[[Iterator[_T]], Collection[_T]]' - ) -> 'Iterator[Collection[_T]]': ... + container_factory: Callable[[Iterator[_T]], Collection[_T]] + ) -> Iterator[Collection[_T]]: ... def batched( self, - iterable: 'Iterable[_T]', + iterable: Iterable[_T], batch_size: int, - container_factory: 'Callable[[Iterator[_T]], Collection[_T]]' = tuple - ) -> 'Iterator[Collection[_T]]': + container_factory: Callable[[Iterator[_T]], Collection[_T]] = tuple + ) -> Iterator[Collection[_T]]: """ See :func:`onegov.core.utils.batched`. """ return utils.batched( @@ -151,7 +153,7 @@ def csrf_protected_url(self, url: str) -> str: """ Adds a csrf token to the given url. """ return utils.append_query_param(url, 'csrf-token', self.csrf_token) - def format_date(self, dt: 'datetime | date | None', format: str) -> str: + def format_date(self, dt: datetime | date | None, format: str) -> str: """ Takes a datetime and formats it according to local timezone and the given format. @@ -207,7 +209,7 @@ def number_symbols(locale: str) -> tuple[str, str]: def format_number( self, - number: 'numbers.Number | Decimal | float | None', + number: numbers.Number | Decimal | float | None, decimal_places: int | None = None, padding: str = '' ) -> str: @@ -240,7 +242,7 @@ def view_name(self) -> str | None: """ return self.request.unconsumed and self.request.unconsumed[-1] or None - def today(self) -> 'date': + def today(self) -> date: return self.now().date() def now(self) -> datetime: @@ -259,12 +261,12 @@ class ChameleonLayout(Layout): """ @cached_property - def template_loader(self) -> 'TemplateLoader': + def template_loader(self) -> TemplateLoader: """ Returns the chameleon template loader. """ return self.request.template_loader @cached_property - def base(self) -> 'PageTemplateFile': + def base(self) -> PageTemplateFile: """ Returns the layout, which defines the base layout of all pages. See ``templates/layout.pt``. @@ -273,7 +275,7 @@ def base(self) -> 'PageTemplateFile': return self.template_loader['layout.pt'] @cached_property - def macros(self) -> 'MacrosLookup': + def macros(self) -> MacrosLookup: """ Returns the macros, which offer often used html constructs. See ``templates/macros.pt``. @@ -281,7 +283,7 @@ def macros(self) -> 'MacrosLookup': return self.template_loader.macros @cached_property - def elements(self) -> 'PageTemplate | PageTemplateFile': + def elements(self) -> PageTemplate | PageTemplateFile: """ The templates used by the elements. Overwrite this with your own ``templates/elements.pt`` if neccessary. diff --git a/src/onegov/core/mail.py b/src/onegov/core/mail.py index a5d059d11b..b00d8a22ef 100644 --- a/src/onegov/core/mail.py +++ b/src/onegov/core/mail.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os.path import magic import re @@ -137,7 +139,7 @@ def format_single_address(address: Address | str) -> str: return f'{name} <{address.addr_spec}>' -def format_address(addresses: 'SequenceOrScalar[Address | str]') -> str: +def format_address(addresses: SequenceOrScalar[Address | str]) -> str: """ Convenience function that accepts both a single Address and a sequence of Address, otherwise identical to format_single_address @@ -168,8 +170,8 @@ class Attachment: # we need to make sure to coerce self.filename to str def __init__( self, - filename: 'StrPath', - content: 'SupportsRead[str | bytes] | str | bytes | None' = None, + filename: StrPath, + content: SupportsRead[str | bytes] | str | bytes | None = None, content_type: str | None = None ): @@ -198,7 +200,7 @@ def __init__( content_type = magic.from_buffer(self.content, mime=True) self.content_type = content_type - def prepare(self) -> 'AttachmentJsonDict': + def prepare(self) -> AttachmentJsonDict: """ Prepares attachment so it can be sent to Postmark API. """ @@ -213,16 +215,16 @@ def prepare(self) -> 'AttachmentJsonDict': def prepare_email( sender: Address | str, reply_to: Address | str | None = None, - receivers: 'SequenceOrScalar[Address | str]' = (), - cc: 'SequenceOrScalar[Address | str]' = (), - bcc: 'SequenceOrScalar[Address | str]' = (), + receivers: SequenceOrScalar[Address | str] = (), + cc: SequenceOrScalar[Address | str] = (), + bcc: SequenceOrScalar[Address | str] = (), subject: str | None = None, content: str | None = None, plaintext: str | None = None, - attachments: 'Iterable[Attachment | StrPath]' = (), + attachments: Iterable[Attachment | StrPath] = (), headers: dict[str, str] | None = None, stream: str = 'marketing' -) -> 'EmailJsonDict': +) -> EmailJsonDict: """ Creates a dictiornary that can be turned into JSON as is and sent to the Postmark API. diff --git a/src/onegov/core/mail_processor/__init__.py b/src/onegov/core/mail_processor/__init__.py index b77f8d9c26..f296786222 100644 --- a/src/onegov/core/mail_processor/__init__.py +++ b/src/onegov/core/mail_processor/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from .postmark import PostmarkMailQueueProcessor from .smtp import SMTPMailQueueProcessor diff --git a/src/onegov/core/mail_processor/core.py b/src/onegov/core/mail_processor/core.py index b9a530a88a..3ade4a5505 100644 --- a/src/onegov/core/mail_processor/core.py +++ b/src/onegov/core/mail_processor/core.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import errno import logging import os diff --git a/src/onegov/core/mail_processor/postmark.py b/src/onegov/core/mail_processor/postmark.py index d049b4685a..b69190a04a 100644 --- a/src/onegov/core/mail_processor/postmark.py +++ b/src/onegov/core/mail_processor/postmark.py @@ -7,6 +7,7 @@ qp = PostmarkQueueProcessor(token, maildir, maildir, ..., limit=x) qp.send_messages() """ +from __future__ import annotations import json import pycurl diff --git a/src/onegov/core/mail_processor/smtp.py b/src/onegov/core/mail_processor/smtp.py index 1cbc993434..b8c8a4a1dc 100644 --- a/src/onegov/core/mail_processor/smtp.py +++ b/src/onegov/core/mail_processor/smtp.py @@ -9,6 +9,7 @@ qp = SMTPEmailQueueProcessor(mailer, maildir1, maildir2, ..., limit=x) qp.send_messages() """ +from __future__ import annotations import json import smtplib diff --git a/src/onegov/core/markdown.py b/src/onegov/core/markdown.py index 6e3fb0913c..53f9858d9d 100644 --- a/src/onegov/core/markdown.py +++ b/src/onegov/core/markdown.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import html from mistletoe import Document, HtmlRenderer # type:ignore[import-untyped] @@ -13,21 +15,21 @@ RENDERER_INSTANCES = {} -class HTMLRendererWithoutInlineHtml(HtmlRenderer): +class HTMLRendererWithoutInlineHtml(HtmlRenderer): # type:ignore[misc] @staticmethod - def render_html_block(token: 'HTMLBlock') -> str: + def render_html_block(token: HTMLBlock) -> str: return html.escape(token.content) @staticmethod - def render_html_span(token: 'HTMLSpan') -> str: + def render_html_span(token: HTMLSpan) -> str: return html.escape(token.content) def render_untrusted_markdown( markdown: str, cls: type[HtmlRenderer] = HTMLRendererWithoutInlineHtml -) -> 'Markup': +) -> Markup: # use a global renderer instance, but only create it if used if cls not in RENDERER_INSTANCES: diff --git a/src/onegov/core/metadata.py b/src/onegov/core/metadata.py index b3f2e0bb84..35dfd56c0a 100644 --- a/src/onegov/core/metadata.py +++ b/src/onegov/core/metadata.py @@ -1,4 +1,5 @@ """ Metadata about the instance, available through HTTP. """ +from __future__ import annotations import hashlib import inspect @@ -34,11 +35,11 @@ public_property = secret_property = property # noqa: TC009 else: - def public_property(fn: 'Callable[[Any], Any]') -> property: + def public_property(fn: Callable[[Any], Any]) -> property: fn.audience = 'public' return property(fn) - def secret_property(fn: 'Callable[[Any], Any]') -> property: + def secret_property(fn: Callable[[Any], Any]) -> property: fn.audience = 'secret' return property(fn) @@ -58,7 +59,7 @@ def for_audiences( def pick( properties: list[tuple[str, Any]] - ) -> 'Iterator[tuple[str, Any]]': + ) -> Iterator[tuple[str, Any]]: for name, prop in properties: if not hasattr(prop, 'fget'): @@ -123,7 +124,7 @@ def get_private_metadata(app: Framework, absorb: str) -> SecretMetadata: @Framework.json(model=PublicMetadata, permission=Public) def view_public_metadata( self: PublicMetadata, - request: 'CoreRequest' + request: CoreRequest ) -> morepath.Response: return render_metadata(self, request) @@ -131,14 +132,14 @@ def view_public_metadata( @Framework.json(model=SecretMetadata, permission=Secret) def view_secret_metadata( self: PublicMetadata, - request: 'CoreRequest' + request: CoreRequest ) -> morepath.Response: return render_metadata(self, request) def render_metadata( self: PublicMetadata | SecretMetadata, - request: 'CoreRequest' + request: CoreRequest ) -> morepath.Response: data = self.as_dict() diff --git a/src/onegov/core/orm/__init__.py b/src/onegov/core/orm/__init__.py index 65392117c0..33f6829ef5 100644 --- a/src/onegov/core/orm/__init__.py +++ b/src/onegov/core/orm/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import psycopg2 from markupsafe import escape, Markup @@ -47,19 +49,19 @@ class ModelBase: @overload @classmethod - def get_polymorphic_class(cls, identity_value: str) -> type['Self']: ... + def get_polymorphic_class(cls, identity_value: str) -> type[Self]: ... @overload @classmethod def get_polymorphic_class(cls, identity_value: str, default: _T - ) -> type['Self'] | _T: ... + ) -> type[Self] | _T: ... @classmethod def get_polymorphic_class( cls, identity_value: str, default: _T = MISSING # type:ignore[assignment] - ) -> type['Self'] | _T: + ) -> type[Self] | _T: """ Returns the polymorphic class if it exists, given the value of the polymorphic identity. @@ -103,8 +105,8 @@ class TranslationMarkupHybrid(TranslationHybrid): def getter_factory( self, - attr: '_TranslatableColumn' - ) -> 'Callable[[object], Markup | None]': + attr: _TranslatableColumn + ) -> Callable[[object], Markup | None]: original_getter = super().getter_factory(attr) @@ -124,8 +126,8 @@ def getter(obj: object) -> Markup | None: def setter_factory( self, - attr: '_TranslatableColumn' - ) -> 'Callable[[object, str | None], None]': + attr: _TranslatableColumn + ) -> Callable[[object, str | None], None]: original_setter = super().setter_factory(attr) @@ -156,8 +158,8 @@ def __call__( # type: ignore[override] def find_models( base: type[_T], - is_match: 'Callable[[type[_T]], bool]' -) -> 'Iterator[type[_T]]': + is_match: Callable[[type[_T]], bool] +) -> Iterator[type[_T]]: """ Finds the ORM models in the given ORM base class that match a filter. The filter is called with each class in the instance and it is supposed @@ -202,7 +204,7 @@ def mark_as_changed(obj: Base, *args: Any, **kwargs: Any) -> None: event.listen(ModelBase, 'attribute_instrument', configure_listener) -def share_session_manager(query: 'Query[Any]') -> None: +def share_session_manager(query: Query[Any]) -> None: session_manager = SessionManager.get_active() for desc in query.column_descriptions: diff --git a/src/onegov/core/orm/abstract/__init__.py b/src/onegov/core/orm/abstract/__init__.py index 69280f8649..05e0ec3416 100644 --- a/src/onegov/core/orm/abstract/__init__.py +++ b/src/onegov/core/orm/abstract/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.abstract.associable import Associable, associated from onegov.core.orm.abstract.adjacency_list import ( AdjacencyList, AdjacencyListCollection, MoveDirection, sort_siblings diff --git a/src/onegov/core/orm/abstract/adjacency_list.py b/src/onegov/core/orm/abstract/adjacency_list.py index 9f52a0a9b8..16fff50561 100644 --- a/src/onegov/core/orm/abstract/adjacency_list.py +++ b/src/onegov/core/orm/abstract/adjacency_list.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from enum import Enum from itertools import chain from lazy_object_proxy import Proxy # type:ignore[import-untyped] @@ -43,8 +45,8 @@ class MoveDirection(Enum): def sort_siblings( - siblings: 'Sequence[_L]', - key: 'Callable[[_L], SupportsRichComparison]', + siblings: Sequence[_L], + key: Callable[[_L], SupportsRichComparison], reverse: bool = False ) -> None: """ Sorts the siblings by the given key, writing the order to the @@ -64,10 +66,10 @@ class AdjacencyList(Base): #: the id fo the db record (only relevant internally) #: do not change this id after creation as that would destroy the tree - id: 'Column[int]' = Column(Integer, primary_key=True) + id: Column[int] = Column(Integer, primary_key=True) if TYPE_CHECKING: - parent_id: 'Column[int | None]' + parent_id: Column[int | None] # subclasses need to override with the correct relationship # with generics there's an issue with class vs instance access # technically AdjacencyList is abstract, so as long as we force @@ -75,32 +77,32 @@ class AdjacencyList(Base): # there is no way to express this in mypy, we could write a # mypy plugin to ensure these relationships get generated # properly... - parent: 'relationship[AdjacencyList | None]' - children: 'relationship[Sequence[AdjacencyList]]' + parent: relationship[AdjacencyList | None] + children: relationship[Sequence[AdjacencyList]] #: the id of the parent @declared_attr # type:ignore[no-redef] - def parent_id(cls) -> 'Column[int | None]': + def parent_id(cls) -> Column[int | None]: return Column(Integer, ForeignKey('{}.id'.format(cls.__tablename__))) #: the name of the item - think of this as the id or better yet #: the url segment e.g. ``parent-item/child-item`` #: #: automatically generated from the title if not provided - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: the human readable title of the item - title: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) #: the type of the item, this can be used to create custom polymorphic #: subclasses of this class. See #: ``_. - type: 'Column[str]' = Column( + type: Column[str] = Column( Text, nullable=False, default=lambda: 'generic') @declared_attr # type:ignore[no-redef] - def children(cls) -> 'relationship[list[Self]]': + def children(cls) -> relationship[list[Self]]: return relationship( cls.__name__, # type:ignore[attr-defined] order_by=cls.order, @@ -117,7 +119,7 @@ def children(cls) -> 'relationship[list[Self]]': #: the order of the items - items are added at the end by default # FIXME: This should probably have been nullable=False - order: 'Column[int]' = Column(Integer, default=2 ** 16) + order: Column[int] = Column(Integer, default=2 ** 16) # default sort order is order, id @declared_attr @@ -130,7 +132,7 @@ def __mapper_args__(cls): # type:ignore @declared_attr def __table_args__(cls): # type:ignore - prefix = cls.__name__.lower() + prefix: str = cls.__name__.lower() # type:ignore[attr-defined] return ( # make sure that no children of a single parent share a name Index( @@ -149,8 +151,8 @@ def __table_args__(cls): # type:ignore # and order by children/siblings Index( prefix + '_order', - nullsfirst('parent_id'), - nullsfirst('"order"') + nullsfirst('parent_id'), # type:ignore[arg-type] + nullsfirst('"order"') # type:ignore[arg-type] ) ) @@ -163,7 +165,7 @@ def validate_name(self, key: None, name: str) -> str: return name @property - def sort_key(self) -> 'Callable[[Self], SupportsRichComparison]': + def sort_key(self) -> Callable[[Self], SupportsRichComparison]: """ The sort key used for sorting the siblings if the title changes. """ @@ -176,15 +178,15 @@ def sort_on_title_change(self, title: str) -> None: ... @declared_attr # type:ignore[no-redef] def sort_on_title_change( cls - ) -> 'Callable[[Self, str], None]': + ) -> Callable[[Self, str], None]: """ Makes sure the A-Z sorting is kept when a title changes. """ - class OldItemProxy(Proxy): + class OldItemProxy(Proxy): # type:ignore[misc] title = None # we need to wrap this here because this is an abstract base class @observes('title') - def sort_on_title_change(self: 'Self', title: str) -> None: + def sort_on_title_change(self: Self, title: str) -> None: # the title value has already changed at this point, and we # probably don't want to touch 'self' which is in transition, @@ -198,7 +200,7 @@ def sort_on_title_change(self: 'Self', title: str) -> None: old_item = OldItemProxy(lambda: self) old_item.title = deleted[0] - def old_sort_key(item: 'Self') -> 'SupportsRichComparison': + def old_sort_key(item: Self) -> SupportsRichComparison: return self.sort_key(item is self and old_item or item) siblings = self.siblings.all() @@ -211,7 +213,7 @@ def old_sort_key(item: 'Self') -> 'SupportsRichComparison': def __init__( self, title: str, - parent: 'Self | None' = None, + parent: Self | None = None, **kwargs: Any ): """ Initializes a new item with the given title. If no parent @@ -229,7 +231,7 @@ def __init__( setattr(self, key, value) @property - def root(self) -> 'AdjacencyList': + def root(self) -> AdjacencyList: """ Returns the root of this item. """ if self.parent is None: return self @@ -237,14 +239,14 @@ def root(self) -> 'AdjacencyList': return self.parent.root @property - def ancestors(self) -> 'Iterator[AdjacencyList]': + def ancestors(self) -> Iterator[AdjacencyList]: """ Returns all ancestors of this item. """ if self.parent: yield from self.parent.ancestors yield self.parent @property - def siblings(self) -> 'Query[Self]': + def siblings(self) -> Query[Self]: """ Returns a query that includes all siblings, including the item itself. @@ -304,17 +306,17 @@ def __listclass__(self) -> type[_L]: """ raise NotImplementedError - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session @staticmethod - def sort_key(item: _L) -> 'SupportsRichComparison': + def sort_key(item: _L) -> SupportsRichComparison: """ The sort key with which the items are sorted into their siblings. """ return normalize_for_url(item.title) - def query(self, ordered: bool = True) -> 'Query[_L]': + def query(self, ordered: bool = True) -> Query[_L]: """ Returns a query using :attr:`AdjacencyListCollection.__listclass__`. @@ -537,7 +539,7 @@ def move(self, subject: _L, target: _L, direction: MoveDirection) -> None: siblings = target.siblings.all() - def new_order() -> 'Iterator[_L]': + def new_order() -> Iterator[_L]: for sibling in siblings: if sibling == subject: continue diff --git a/src/onegov/core/orm/abstract/associable.py b/src/onegov/core/orm/abstract/associable.py index ba2bbaa03a..cbde49be29 100644 --- a/src/onegov/core/orm/abstract/associable.py +++ b/src/onegov/core/orm/abstract/associable.py @@ -56,6 +56,7 @@ class Product(Base, Payable): ``payments_for_products`` table. """ +from __future__ import annotations from onegov.core.orm.utils import QueryChain from sqlalchemy import Column @@ -82,11 +83,11 @@ class Product(Base, Payable): class RegisteredLink(NamedTuple): - cls: type['Base'] + cls: type[Base] table: Table key: str attribute: str - cardinality: 'Cardinality' + cardinality: Cardinality @property def class_attribute(self) -> Any: @@ -102,7 +103,7 @@ def associated( uselist: Literal['auto'] = ..., backref_suffix: str = ..., onupdate: str | None = ... -) -> 'rel[list[_M]]': ... +) -> rel[list[_M]]: ... @overload @@ -114,41 +115,41 @@ def associated( uselist: Literal['auto'] = ..., backref_suffix: str = ..., onupdate: str | None = ... -) -> 'rel[_M | None]': ... +) -> rel[_M | None]: ... @overload def associated( associated_cls: type[_M], attribute_name: str, - cardinality: 'Cardinality' = ..., + cardinality: Cardinality = ..., *, uselist: Literal[True], backref_suffix: str = ..., onupdate: str | None = ... -) -> 'rel[list[_M]]': ... +) -> rel[list[_M]]: ... @overload def associated( associated_cls: type[_M], attribute_name: str, - cardinality: 'Cardinality' = ..., + cardinality: Cardinality = ..., *, uselist: Literal[False], backref_suffix: str = ..., onupdate: str | None = ... -) -> 'rel[_M | None]': ... +) -> rel[_M | None]: ... def associated( associated_cls: type[_M], attribute_name: str, - cardinality: 'Cardinality' = 'one-to-many', + cardinality: Cardinality = 'one-to-many', uselist: Literal['auto'] | bool = 'auto', backref_suffix: str = '__tablename__', onupdate: str | None = None -) -> 'rel[list[_M]] | rel[_M | None]': +) -> rel[list[_M]] | rel[_M | None]: """ Creates an associated attribute. This attribute is supposed to be defined on the mixin class that will establish the generic association if inherited by a model. @@ -202,7 +203,7 @@ class Company(Base, Addressable): if uselist == 'auto': uselist = not cardinality.endswith('to-one') - def descriptor(cls: type['Base']) -> 'rel[list[_M]] | rel[_M | None]': + def descriptor(cls: type[Base]) -> rel[list[_M]] | rel[_M | None]: # HACK: forms is one of the only tables which doesn't use id as # its primary key, we probably should just use id everywhere # consistently @@ -322,7 +323,7 @@ class Associable: __tablename__: ClassVar[str] @classmethod - def association_base(cls) -> type['Associable']: + def association_base(cls) -> type[Associable]: """ Returns the model which directly inherits from Associable. """ for parent in cls.__bases__: @@ -337,11 +338,11 @@ def association_base(cls) -> type['Associable']: def register_link( cls, link_name: str, - linked_class: type['Base'], + linked_class: type[Base], table: Table, key: str, attribute: str, - cardinality: 'Cardinality' + cardinality: Cardinality ) -> None: """ All associated classes are registered through this method. This yields the following benefits: @@ -370,7 +371,7 @@ def register_link( ) @property - def links(self) -> 'QueryChain[Base]': + def links(self) -> QueryChain[Base]: """ Returns a query chain with all records of all models which attach to the associable model. @@ -379,7 +380,7 @@ def links(self) -> 'QueryChain[Base]': session = object_session(self) - def query(link: RegisteredLink) -> 'Query[Base]': + def query(link: RegisteredLink) -> Query[Base]: column = getattr(link.cls, link.attribute) q = session.query(link.cls) diff --git a/src/onegov/core/orm/cache.py b/src/onegov/core/orm/cache.py index 0126f14008..de65e28ab6 100644 --- a/src/onegov/core/orm/cache.py +++ b/src/onegov/core/orm/cache.py @@ -20,6 +20,7 @@ def users(self): cache is usually a shared redis instance, this works for multiple processes. """ +from __future__ import annotations import inspect @@ -69,18 +70,18 @@ class _OrmCacheDecorator(Protocol): @overload def __call__( self, - fn: 'Creator[Query[_T]]' - ) -> 'OrmCacheDescriptor[tuple[_T, ...]]': ... + fn: Creator[Query[_T]] + ) -> OrmCacheDescriptor[tuple[_T, ...]]: ... @overload def __call__( self, - fn: 'Creator[_T]' - ) -> 'OrmCacheDescriptor[_T]': ... + fn: Creator[_T] + ) -> OrmCacheDescriptor[_T]: ... class _HasApp(Protocol): @property - def app(self) -> 'OrmCacheApp': ... + def app(self) -> OrmCacheApp: ... _T = TypeVar('_T') _QT = TypeVar('_QT') @@ -131,8 +132,8 @@ def setup_orm_cache(self) -> None: def descriptor_bound_orm_change_handler( self, - descriptor: 'OrmCacheDescriptor[Any]' - ) -> 'Callable[[str, Base], None]': + descriptor: OrmCacheDescriptor[Any] + ) -> Callable[[str, Base], None]: """ Listens to changes to the database and evicts the cache if the policy demands it. Available policies: @@ -144,7 +145,7 @@ def descriptor_bound_orm_change_handler( """ - def handle_orm_change(schema: str, obj: 'Base') -> None: + def handle_orm_change(schema: str, obj: Base) -> None: if callable(descriptor.cache_policy): dirty = descriptor.cache_policy(obj) @@ -180,7 +181,7 @@ def handle_orm_change(schema: str, obj: 'Base') -> None: return handle_orm_change @property - def orm_cache_descriptors(self) -> 'Iterator[OrmCacheDescriptor[Any]]': + def orm_cache_descriptors(self) -> Iterator[OrmCacheDescriptor[Any]]: """ Yields all orm cache descriptors installed on the class. """ for member_name, member in inspect.getmembers(self.__class__): @@ -207,24 +208,24 @@ class OrmCacheDescriptor(Generic[_T]): @overload def __init__( - self: 'OrmCacheDescriptor[tuple[_QT, ...]]', - cache_policy: 'CachePolicy', - creator: 'Creator[Query[_QT]]', + self: OrmCacheDescriptor[tuple[_QT, ...]], + cache_policy: CachePolicy, + creator: Creator[Query[_QT]], by_role: bool = False ): ... @overload def __init__( - self: 'OrmCacheDescriptor[_T]', - cache_policy: 'CachePolicy', - creator: 'Creator[_T]', + self: OrmCacheDescriptor[_T], + cache_policy: CachePolicy, + creator: Creator[_T], by_role: bool = False ): ... def __init__( self, - cache_policy: 'CachePolicy', - creator: 'Creator[Query[Any]] | Creator[_T]', + cache_policy: CachePolicy, + creator: Creator[Query[Any]] | Creator[_T], by_role: bool = False ): self.cache_policy = cache_policy @@ -233,7 +234,7 @@ def __init__( self.creator = creator self.by_role = by_role - def cache_key(self, obj: 'OrmCacheApp | _HasApp') -> str: + def cache_key(self, obj: OrmCacheApp | _HasApp) -> str: if not self.by_role: return self.cache_key_prefix @@ -271,7 +272,7 @@ def assert_no_orm_objects(self, obj: object, depth: int = 0) -> None: for child in obj: self.assert_no_orm_objects(obj, depth + 1) - def create(self, instance: 'OrmCacheApp | _HasApp') -> _T: + def create(self, instance: OrmCacheApp | _HasApp) -> _T: """ Uses the creator to load the object to be cached. Since the return value of the creator might not be something we want @@ -288,7 +289,7 @@ def create(self, instance: 'OrmCacheApp | _HasApp') -> _T: self.assert_no_orm_objects(result) return result - def load(self, instance: 'OrmCacheApp | _HasApp') -> _T: + def load(self, instance: OrmCacheApp | _HasApp) -> _T: """ Loads the object from the database or cache. """ if isinstance(instance, OrmCacheApp): @@ -361,7 +362,7 @@ def __get__( self, instance: None, owner: type[Any] - ) -> 'Self': ... + ) -> Self: ... @overload def __get__( @@ -374,7 +375,7 @@ def __get__( self, instance: Any | None, owner: type[Any] - ) -> 'Self | _T': + ) -> Self | _T: """ Handles the object/cache access. """ if instance is None: @@ -384,9 +385,9 @@ def __get__( def orm_cached( - policy: 'CachePolicy', + policy: CachePolicy, by_role: bool = False -) -> '_OrmCacheDecorator': +) -> _OrmCacheDecorator: """ The decorator use to setup the cache descriptor. See the :mod:`onegov.core.orm.cache` docs for usage. @@ -395,22 +396,22 @@ def orm_cached( @overload def orm_cache_decorator( - fn: 'Creator[Query[_T]]' - ) -> 'OrmCacheDescriptor[tuple[_T, ...]]': ... + fn: Creator[Query[_T]] + ) -> OrmCacheDescriptor[tuple[_T, ...]]: ... @overload def orm_cache_decorator( - fn: 'Creator[_T]' - ) -> 'OrmCacheDescriptor[_T]': ... + fn: Creator[_T] + ) -> OrmCacheDescriptor[_T]: ... - def orm_cache_decorator(fn: 'Creator[Any]') -> 'OrmCacheDescriptor[Any]': + def orm_cache_decorator(fn: Creator[Any]) -> OrmCacheDescriptor[Any]: return OrmCacheDescriptor(policy, fn, by_role) return orm_cache_decorator def request_cached( - appmethod: 'Callable[[_FrameworkT], _T]' -) -> '_RequestCached[_FrameworkT, _T]': + appmethod: Callable[[_FrameworkT], _T] +) -> _RequestCached[_FrameworkT, _T]: """ This is like a request scoped :func:`orm_cached`. This may store ORM objects in contrast to :func:`orm_cached`, which @@ -421,7 +422,7 @@ def request_cached( cache_key = appmethod.__qualname__ @wraps(appmethod) - def wrapper(self: '_FrameworkT') -> _T: + def wrapper(self: _FrameworkT) -> _T: session = self.session() # before accessing any cached values we need to make sure that all diff --git a/src/onegov/core/orm/debug.py b/src/onegov/core/orm/debug.py index 81819d374d..722c1acc34 100644 --- a/src/onegov/core/orm/debug.py +++ b/src/onegov/core/orm/debug.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import click from contextlib import contextmanager @@ -26,7 +28,7 @@ class Timer: def start(self) -> None: self.started = utcnow() - def stop(self) -> 'timedelta': + def stop(self) -> timedelta: return utcnow() - self.started @@ -41,7 +43,7 @@ def print_query(query: bytes) -> None: @contextmanager def analyze_sql_queries( report: Literal['summary', 'redundant', 'all'] = 'summary' -) -> 'Iterator[None]': +) -> Iterator[None]: """ Analyzes the sql-queries executed during its context. There are three levels of information (report argument): @@ -61,24 +63,24 @@ def analyze_sql_queries( queries = {} timer = Timer() - @event.listens_for(Engine, 'before_cursor_execute') + @event.listens_for(Engine, 'before_cursor_execute') # type:ignore[misc] def before_exec( - conn: 'Connection', + conn: Connection, cursor: Any, statement: str, parameters: Any, - context: 'ExecutionContext', + context: ExecutionContext, executemany: bool ) -> None: timer.start() - @event.listens_for(Engine, 'after_cursor_execute') + @event.listens_for(Engine, 'after_cursor_execute') # type:ignore[misc] def after_exec( - conn: 'Connection', + conn: Connection, cursor: Any, statement: str, parameters: Any, - context: 'ExecutionContext', + context: ExecutionContext, executemany: bool ) -> None: runtime = timer.stop() diff --git a/src/onegov/core/orm/func.py b/src/onegov/core/orm/func.py index 84f5d220c3..685fac7098 100644 --- a/src/onegov/core/orm/func.py +++ b/src/onegov/core/orm/func.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sqlalchemy.sql.functions import ReturnTypeFromArgs from typing import TypeVar, TYPE_CHECKING diff --git a/src/onegov/core/orm/mixins/__init__.py b/src/onegov/core/orm/mixins/__init__.py index d1b3f1a7b6..6eb38c0d47 100644 --- a/src/onegov/core/orm/mixins/__init__.py +++ b/src/onegov/core/orm/mixins/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.mixins.content import content_property from onegov.core.orm.mixins.content import ContentMixin from onegov.core.orm.mixins.content import data_property diff --git a/src/onegov/core/orm/mixins/content.py b/src/onegov/core/orm/mixins/content.py index 73044ef3e0..efc87ec217 100644 --- a/src/onegov/core/orm/mixins/content.py +++ b/src/onegov/core/orm/mixins/content.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from markupsafe import escape, Markup from onegov.core.orm.types import JSON, MarkupText from sqlalchemy import type_coerce @@ -24,24 +26,24 @@ def __call__( key: str | None = None, default: None = None, value_type: None = None - ) -> 'dict_property[Any | None]': ... + ) -> dict_property[Any | None]: ... @overload def __call__( self, key: str | None, - default: '_T | Callable[[], _T]', + default: _T | Callable[[], _T], value_type: None = None - ) -> 'dict_property[_T]': ... + ) -> dict_property[_T]: ... @overload def __call__( self, key: str | None = None, *, - default: '_T | Callable[[], _T]', + default: _T | Callable[[], _T], value_type: None = None - ) -> 'dict_property[_T]': ... + ) -> dict_property[_T]: ... @overload def __call__( @@ -49,8 +51,8 @@ def __call__( key: str | None, default: None, *, - value_type: 'type[_T]' - ) -> 'dict_property[_T]': ... + value_type: type[_T] + ) -> dict_property[_T]: ... @overload def __call__( @@ -58,25 +60,25 @@ def __call__( key: str | None = None, default: None = None, *, - value_type: 'type[_T]' - ) -> 'dict_property[_T]': ... + value_type: type[_T] + ) -> dict_property[_T]: ... @overload def __call__( self, key: str | None, - default: '_T | Callable[[], _T]', - value_type: 'type[_T]' - ) -> 'dict_property[_T]': ... + default: _T | Callable[[], _T], + value_type: type[_T] + ) -> dict_property[_T]: ... @overload def __call__( self, key: str | None = None, *, - default: '_T | Callable[[], _T]', - value_type: 'type[_T]' - ) -> 'dict_property[_T]': ... + default: _T | Callable[[], _T], + value_type: type[_T] + ) -> dict_property[_T]: ... _T = TypeVar('_T') @@ -99,12 +101,12 @@ class ContentMixin: #: metadata associated with the form, for storing small amounts of data @declared_attr # type:ignore[no-redef] - def meta(cls) -> 'Column[dict[str, Any]]': + def meta(cls) -> Column[dict[str, Any]]: return Column(JSON, nullable=False, default=dict) #: content associated with the form, for storing things like long texts @declared_attr # type:ignore[no-redef] - def content(cls) -> 'Column[dict[str, Any]]': + def content(cls) -> Column[dict[str, Any]]: return deferred(Column(JSON, nullable=False, default=dict)) @@ -208,16 +210,16 @@ class Model(ContentMixin): is_attribute = True - custom_getter: 'Callable[[Any], _T] | None' - custom_expression: 'Callable[[type[Any]], ColumnElement[_T]] | None' - custom_setter: 'Callable[[Any, _T], None] | None' - custom_deleter: 'Callable[[Any], None] | None' + custom_getter: Callable[[Any], _T] | None + custom_expression: Callable[[type[Any]], ColumnElement[_T]] | None + custom_setter: Callable[[Any, _T], None] | None + custom_deleter: Callable[[Any], None] | None @overload def __init__( # TODO: We probably want to change this to `dict_property[_T | None]` # eventually so mypy complains about the missing LHS annotation - self: 'dict_property[Any | None]', + self: dict_property[Any | None], attribute: str, key: str | None = None, default: None = None, @@ -226,26 +228,26 @@ def __init__( @overload def __init__( - self: 'dict_property[_T]', + self: dict_property[_T], attribute: str, key: str | None, - default: '_T | Callable[[], _T]', + default: _T | Callable[[], _T], value_type: None = None ): ... @overload def __init__( - self: 'dict_property[_T]', + self: dict_property[_T], attribute: str, key: str | None = None, *, - default: '_T | Callable[[], _T]', + default: _T | Callable[[], _T], value_type: None = None ): ... @overload def __init__( - self: 'dict_property[_T]', + self: dict_property[_T], attribute: str, key: str | None, default: None, @@ -255,7 +257,7 @@ def __init__( @overload def __init__( - self: 'dict_property[_T]', + self: dict_property[_T], attribute: str, key: str | None = None, default: None = None, @@ -265,20 +267,20 @@ def __init__( @overload def __init__( - self: 'dict_property[_T]', + self: dict_property[_T], attribute: str, key: str | None, - default: '_T | Callable[[], _T]', + default: _T | Callable[[], _T], value_type: type[_T] ): ... @overload def __init__( - self: 'dict_property[_T]', + self: dict_property[_T], attribute: str, key: str | None = None, *, - default: '_T | Callable[[], _T]', + default: _T | Callable[[], _T], value_type: type[_T] ): ... @@ -318,24 +320,24 @@ def __set_name__(self, owner: type[object], name: str) -> None: self.key = name @property - def getter(self) -> 'Callable[[Callable[[Any], _T]], Self]': - def wrapper(fn: 'Callable[[Any], _T]') -> Any: + def getter(self) -> Callable[[Callable[[Any], _T]], Self]: + def wrapper(fn: Callable[[Any], _T]) -> Any: self.custom_getter = fn return self return wrapper @property - def setter(self) -> 'Callable[[Callable[[Any, _T], None]], Self]': - def wrapper(fn: 'Callable[[Any, _T], None]') -> Any: + def setter(self) -> Callable[[Callable[[Any, _T], None]], Self]: + def wrapper(fn: Callable[[Any, _T], None]) -> Any: self.custom_setter = fn return self return wrapper @property - def deleter(self) -> 'Callable[[Callable[[Any], None]], Self]': - def wrapper(fn: 'Callable[[Any], None]') -> Any: + def deleter(self) -> Callable[[Callable[[Any], None]], Self]: + def wrapper(fn: Callable[[Any], None]) -> Any: self.custom_deleter = fn return self @@ -344,14 +346,14 @@ def wrapper(fn: 'Callable[[Any], None]') -> Any: @property def expression( self - ) -> 'Callable[[Callable[[Any], ColumnElement[_T]]], Self]': - def wrapper(fn: 'Callable[[Any], ColumnElement[_T]]') -> Any: + ) -> Callable[[Callable[[Any], ColumnElement[_T]]], Self]: + def wrapper(fn: Callable[[Any], ColumnElement[_T]]) -> Any: self.custom_expression = fn return self return wrapper - def _expr(self, owner: type[Any]) -> 'QueryableAttribute | None': + def _expr(self, owner: type[Any]) -> QueryableAttribute | None: # FIXME: We should be able to remove this Any in SQlAlchemy 2.0 expr: Any if self.custom_expression is not None: @@ -388,7 +390,7 @@ def __get__( self, instance: None, owner: type[object] - ) -> 'QueryableAttribute | None': ... + ) -> QueryableAttribute | None: ... @overload def __get__( @@ -401,7 +403,7 @@ def __get__( self, instance: object | None, owner: type[object] - ) -> '_T | QueryableAttribute | None': + ) -> _T | QueryableAttribute | None: if instance is None: return self._expr(owner) @@ -446,7 +448,7 @@ class dict_markup_property(dict_property[_MarkupT]): # noqa: N801 @overload def __init__( - self: 'dict_markup_property[Markup | None]', + self: dict_markup_property[Markup | None], attribute: str, key: str | None = None, default: None = None, @@ -454,7 +456,7 @@ def __init__( @overload def __init__( - self: 'dict_markup_property[Markup]', + self: dict_markup_property[Markup], attribute: str, key: str | None, default: Markup, @@ -462,7 +464,7 @@ def __init__( @overload def __init__( - self: 'dict_markup_property[Markup]', + self: dict_markup_property[Markup], attribute: str, key: str | None = None, *, @@ -496,7 +498,7 @@ def __get__( self, instance: None, owner: type[object] - ) -> 'QueryableAttribute | None': ... + ) -> QueryableAttribute | None: ... @overload def __get__( @@ -509,7 +511,7 @@ def __get__( self, instance: object | None, owner: type[object] - ) -> '_MarkupT | QueryableAttribute | None': + ) -> _MarkupT | QueryableAttribute | None: if instance is None: return self._expr(owner) @@ -546,7 +548,7 @@ def __set__(self, instance: object, value: _MarkupT) -> None: ) -def dict_property_factory(attribute: str) -> '_dict_property_factory': +def dict_property_factory(attribute: str) -> _dict_property_factory: def factory( key: str | None = None, default: Any | None = None, diff --git a/src/onegov/core/orm/mixins/publication.py b/src/onegov/core/orm/mixins/publication.py index baf5c33324..8086366d78 100644 --- a/src/onegov/core/orm/mixins/publication.py +++ b/src/onegov/core/orm/mixins/publication.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sedate import utcnow from sqlalchemy import Column, case, func, and_, not_ from sqlalchemy.ext.hybrid import hybrid_property @@ -34,7 +36,7 @@ def publication_started(self) -> bool: return self.publication_start <= utcnow() @publication_started.expression # type:ignore[no-redef] - def publication_started(cls) -> 'ClauseElement': + def publication_started(cls) -> ClauseElement: return case(( ( cls.publication_start == None, @@ -49,7 +51,7 @@ def publication_ended(self) -> bool: return self.publication_end < utcnow() @publication_ended.expression # type:ignore[no-redef] - def publication_ended(cls) -> 'ClauseElement': + def publication_ended(cls) -> ClauseElement: return case(( ( cls.publication_end == None, @@ -62,5 +64,5 @@ def published(self) -> bool: return self.publication_started and not self.publication_ended @published.expression # type:ignore[no-redef] - def published(cls) -> 'ClauseElement': + def published(cls) -> ClauseElement: return and_(cls.publication_started, not_(cls.publication_ended)) diff --git a/src/onegov/core/orm/mixins/timestamp.py b/src/onegov/core/orm/mixins/timestamp.py index 08ed08662c..f5eb1473fe 100644 --- a/src/onegov/core/orm/mixins/timestamp.py +++ b/src/onegov/core/orm/mixins/timestamp.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.types import UTCDateTime from sedate import utcnow from sqlalchemy.ext.declarative import declared_attr @@ -21,7 +23,7 @@ class TimestampMixin: """ @staticmethod - def timestamp() -> 'datetime': + def timestamp() -> datetime: return utcnow() def force_update(self) -> None: @@ -36,24 +38,24 @@ def force_update(self) -> None: # to type check the implementation though, hence the # `type:ignore[no-redef]` below, rather than putting # the definitions inside the else block - created: 'Column[datetime]' - modified: 'Column[datetime | None]' - last_change: 'Column[datetime]' + created: Column[datetime] + modified: Column[datetime | None] + last_change: Column[datetime] @declared_attr # type:ignore[no-redef] - def created(cls) -> 'Column[datetime]': + def created(cls) -> Column[datetime]: # FIXME: This probably should have been nullable=False return Column(UTCDateTime, default=cls.timestamp) @declared_attr # type:ignore[no-redef] - def modified(cls) -> 'Column[datetime | None]': + def modified(cls) -> Column[datetime | None]: return Column(UTCDateTime, onupdate=cls.timestamp) @hybrid_property # type:ignore[no-redef] - def last_change(self) -> 'datetime': + def last_change(self) -> datetime: """ Returns the self.modified if not NULL, else self.created. """ return self.modified or self.created @last_change.expression # type:ignore[no-redef] - def last_change(cls) -> 'ClauseElement': + def last_change(cls) -> ClauseElement: return func.coalesce(cls.modified, cls.created) diff --git a/src/onegov/core/orm/observer.py b/src/onegov/core/orm/observer.py index bd8da0fac5..4c63022ad3 100644 --- a/src/onegov/core/orm/observer.py +++ b/src/onegov/core/orm/observer.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sqlalchemy_utils.observer from dectate.tool import resolve_dotted_name from functools import wraps @@ -28,11 +30,11 @@ class ScopedPropertyObserver(sqlalchemy_utils.observer.PropertyObserver): or not. """ - _global_observer: ClassVar['ScopedPropertyObserver'] - _scoped_observers: ClassVar[dict[str, 'ScopedPropertyObserver']] + _global_observer: ClassVar[ScopedPropertyObserver] + _scoped_observers: ClassVar[dict[str, ScopedPropertyObserver]] _scoped_observers = {} - def __new__(cls, dotted_name: str | None) -> 'ScopedPropertyObserver': + def __new__(cls, dotted_name: str | None) -> ScopedPropertyObserver: # noqa: PYI034 # special case global scope if dotted_name is None: @@ -97,7 +99,7 @@ def deactivate(self) -> None: def update_generator_registry( self, - mapper: 'Mapper', + mapper: Mapper, class_: type[Any] ) -> None: @@ -113,7 +115,7 @@ def update_generator_registry( ) @classmethod - def enter_scope(cls, application: 'Framework') -> None: + def enter_scope(cls, application: Framework) -> None: for observer in cls._scoped_observers.values(): if isinstance(application, observer.scope): observer.activate() @@ -121,7 +123,7 @@ def enter_scope(cls, application: 'Framework') -> None: observer.deactivate() @classmethod - def enter_class_scope(cls, application_cls: type['Framework']) -> None: + def enter_class_scope(cls, application_cls: type[Framework]) -> None: for observer in cls._scoped_observers.values(): if issubclass(application_cls, observer.scope): observer.activate() @@ -135,12 +137,12 @@ def __repr__(self) -> str: def observes( *paths: str, scope: str | None = None -) -> 'Callable[[_F], _F]': +) -> Callable[[_F], _F]: observer = ScopedPropertyObserver(scope) observer.register_listeners() - def decorator(func: '_F') -> '_F': + def decorator(func: _F) -> _F: @wraps(func) def wrapper(self: Any, *args: Any, **kwargs: Any) -> Any: return func(self, *args, **kwargs) diff --git a/src/onegov/core/orm/session_manager.py b/src/onegov/core/orm/session_manager.py index 9f94f0c677..84d93fbf38 100644 --- a/src/onegov/core/orm/session_manager.py +++ b/src/onegov/core/orm/session_manager.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import threading import re import weakref @@ -52,9 +54,9 @@ def delete(self, synchronize_session: Any = None) -> int: def query_schemas( - connection: 'Connection | Engine', + connection: Connection | Engine, namespace: str | None = None -) -> 'Iterator[str]': +) -> Iterator[str]: """ Yields all schemas or the ones with the given namespace. """ query = text(""" @@ -279,7 +281,7 @@ def on_delete(schema, obj): ) self.register_session(self.session_factory) - def register_engine(self, engine: 'Engine') -> None: + def register_engine(self, engine: Engine) -> None: """ Takes the given engine and registers it with the schema switching mechanism. Maybe used to register external engines with the session manager. @@ -289,9 +291,9 @@ def register_engine(self, engine: 'Engine') -> None: """ - @event.listens_for(engine, 'before_cursor_execute') + @event.listens_for(engine, 'before_cursor_execute') # type:ignore[misc] def activate_schema( - connection: 'Connection', + connection: Connection, cursor: Any, *args: Any, **kwargs: Any @@ -313,9 +315,9 @@ def activate_schema( if schema is not None: cursor.execute('SET search_path TO %s, extensions', (schema, )) - @event.listens_for(engine, 'before_cursor_execute') + @event.listens_for(engine, 'before_cursor_execute') # type:ignore[misc] def limit_session_lifetime( - connection: 'Connection', + connection: Connection, cursor: Any, *args: Any, **kwargs: Any @@ -327,7 +329,7 @@ def limit_session_lifetime( (f'{CONNECTION_LIFETIME}s', ) ) - def register_session(self, session: 'Session') -> None: + def register_session(self, session: Session) -> None: """ Takes the given session and registers it with zope.sqlalchemy and various orm events. @@ -365,17 +367,17 @@ def prevent_bulk_changes_on_aggregate_modules( to have both aggregates and bulk updates/deletes. """ - @event.listens_for(session, 'after_flush') + @event.listens_for(session, 'after_flush') # type:ignore[misc] def on_after_flush( - session: 'Session', + session: Session, flush_context: Any ) -> None: for signal, get_objects in signals: if signal.receivers: - for obj in get_objects(session): + for obj in get_objects(session): # type:ignore[no-untyped-call] signal.send(self.current_schema, obj=obj) - @event.listens_for(session, 'after_bulk_update') + @event.listens_for(session, 'after_bulk_update') # type:ignore[misc] def on_after_bulk_update(update_context: Any) -> None: prevent_bulk_changes_on_aggregate_modules( update_context.mapper.class_) @@ -392,7 +394,7 @@ def on_after_bulk_update(update_context: Any) -> None: for obj in update_context.matched_objects: self.on_update.send(self.current_schema, obj=obj) - @event.listens_for(session, 'after_bulk_delete') + @event.listens_for(session, 'after_bulk_delete') # type:ignore[misc] def on_after_bulk_delete(delete_context: Any) -> None: prevent_bulk_changes_on_aggregate_modules( delete_context.mapper.class_) @@ -451,14 +453,14 @@ def deactivate(self) -> None: self.set_active(None) @classmethod - def set_active(cls, session_manager: 'SessionManager | None') -> None: + def set_active(cls, session_manager: SessionManager | None) -> None: if session_manager: cls._thread_bound._active = weakref.proxy(session_manager) else: cls._thread_bound._active = None @classmethod - def get_active(cls) -> 'SessionManager | None': + def get_active(cls) -> SessionManager | None: try: return cls._thread_bound._active except (AttributeError, ReferenceError): @@ -583,14 +585,14 @@ def create_schema_if_not_exists( if not self.is_schema_found_on_database(schema): self.create_schema(schema, validate) - def bind_session(self, session: '_S') -> '_S': + def bind_session(self, session: _S) -> _S: """ Bind the session to the current schema. """ session.info['schema'] = self.current_schema session.connection().info['session'] = weakref.proxy(session) return session - def session(self) -> 'Session': + def session(self) -> Session: """ Returns a new session or an existing session. Sessions with different schemas are kept independent, though they might reuse each others connections. diff --git a/src/onegov/core/orm/sql.py b/src/onegov/core/orm/sql.py index 9a21fdcfc5..5600bbea5f 100644 --- a/src/onegov/core/orm/sql.py +++ b/src/onegov/core/orm/sql.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os import pglast # type:ignore[import-untyped] import re @@ -20,7 +22,7 @@ NESTED_TYPE = re.compile(r'(\w+)\((\w+)\)') -def as_selectable(query: str, alias: str | None = None) -> 'Alias': +def as_selectable(query: str, alias: str | None = None) -> Alias: """ Takes a raw SQL query and turns it into a selectable SQLAlchemy expression using annotations in comments. @@ -67,7 +69,7 @@ def as_selectable(query: str, alias: str | None = None) -> 'Alias': def type_by_string( expression: str -) -> 'type[TypeEngine[Any]] | TypeEngine[Any]': +) -> type[TypeEngine[Any]] | TypeEngine[Any]: nested_match = NESTED_TYPE.match(expression) if nested_match: @@ -81,7 +83,7 @@ def type_by_string( @lru_cache(maxsize=64) -def as_selectable_from_path(path: str) -> 'Alias': +def as_selectable_from_path(path: str) -> Alias: alias = os.path.basename(path).split('.', 1)[0] with open(path) as f: @@ -89,9 +91,9 @@ def as_selectable_from_path(path: str) -> 'Alias': def column_names_with_comments( - statement: 'RawStmt', + statement: RawStmt, query: str -) -> 'Iterator[tuple[str, str]]': +) -> Iterator[tuple[str, str]]: for target in statement.stmt.targetList: diff --git a/src/onegov/core/orm/types/__init__.py b/src/onegov/core/orm/types/__init__.py index 0455c98ea2..5d6a239433 100644 --- a/src/onegov/core/orm/types/__init__.py +++ b/src/onegov/core/orm/types/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.types.hstore_type import HSTORE from onegov.core.orm.types.json_type import JSON from onegov.core.orm.types.markup_text_type import MarkupText diff --git a/src/onegov/core/orm/types/hstore_type.py b/src/onegov/core/orm/types/hstore_type.py index 9406764276..b67f543153 100644 --- a/src/onegov/core/orm/types/hstore_type.py +++ b/src/onegov/core/orm/types/hstore_type.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sqlalchemy.dialects.postgresql import HSTORE as HSTOREBase from sqlalchemy.ext.mutable import MutableDict @@ -6,4 +8,4 @@ class HSTORE(HSTOREBase): """ Extends the default HSTORE type to make it mutable by default. """ -MutableDict.associate_with(HSTORE) +MutableDict.associate_with(HSTORE) # type:ignore[no-untyped-call] diff --git a/src/onegov/core/orm/types/json_type.py b/src/onegov/core/orm/types/json_type.py index 3eab10bffc..34902c3505 100644 --- a/src/onegov/core/orm/types/json_type.py +++ b/src/onegov/core/orm/types/json_type.py @@ -4,6 +4,8 @@ # to read each others json. # # Therefore we use a common denominator kind of json encoder/decoder. +from __future__ import annotations + from sqlalchemy.ext.mutable import MutableDict from sqlalchemy.types import TypeDecorator from sqlalchemy.dialects.postgresql import JSONB @@ -35,7 +37,7 @@ class JSON(_Base): def process_bind_param( # type:ignore[override] self, value: dict[str, Any] | None, - dialect: 'Dialect' + dialect: Dialect ) -> dict[str, Any]: return {} if value is None else value @@ -43,10 +45,10 @@ def process_bind_param( # type:ignore[override] def process_result_value( self, value: dict[str, Any] | None, - dialect: 'Dialect' + dialect: Dialect ) -> dict[str, Any]: return {} if value is None else value -MutableDict.associate_with(JSON) +MutableDict.associate_with(JSON) # type:ignore[no-untyped-call] diff --git a/src/onegov/core/orm/types/lowercase_text_type.py b/src/onegov/core/orm/types/lowercase_text_type.py index 9794c82f2b..5b229d206a 100644 --- a/src/onegov/core/orm/types/lowercase_text_type.py +++ b/src/onegov/core/orm/types/lowercase_text_type.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sqlalchemy.types import TypeDecorator, TEXT from sqlalchemy_utils.operators import CaseInsensitiveComparator @@ -21,7 +23,7 @@ class LowercaseText(_Base): def process_bind_param( self, value: str | None, - dialect: 'Dialect' + dialect: Dialect ) -> str | None: return None if value is None else value.lower() diff --git a/src/onegov/core/orm/types/markup_text_type.py b/src/onegov/core/orm/types/markup_text_type.py index d7c78d4770..278a85de34 100644 --- a/src/onegov/core/orm/types/markup_text_type.py +++ b/src/onegov/core/orm/types/markup_text_type.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from markupsafe import escape, Markup from sqlalchemy.types import TypeDecorator, TEXT @@ -20,7 +22,7 @@ class MarkupText(_Base): def process_bind_param( self, value: str | None, - dialect: 'Dialect' + dialect: Dialect ) -> Markup | None: return None if value is None else escape(value) @@ -28,7 +30,7 @@ def process_bind_param( def process_literal_param( self, value: str | None, - dialect: 'Dialect' + dialect: Dialect ) -> Markup | None: return None if value is None else escape(value) @@ -36,7 +38,7 @@ def process_literal_param( def process_result_value( self, value: str | None, - dialect: 'Dialect' + dialect: Dialect ) -> Markup | None: # NOTE: It would be safer to sanitize the text, in case someone diff --git a/src/onegov/core/orm/types/utcdatetime_type.py b/src/onegov/core/orm/types/utcdatetime_type.py index c2a5602fb4..5be938e442 100644 --- a/src/onegov/core/orm/types/utcdatetime_type.py +++ b/src/onegov/core/orm/types/utcdatetime_type.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sedate import standardize_date, to_timezone from sqlalchemy.types import DateTime, TypeDecorator @@ -27,9 +29,9 @@ def __init__(self) -> None: def process_bind_param( # type:ignore[override] self, - value: 'datetime | None', - dialect: 'Dialect' - ) -> 'datetime | None': + value: datetime | None, + dialect: Dialect + ) -> datetime | None: if value is None: return None @@ -37,9 +39,9 @@ def process_bind_param( # type:ignore[override] def process_result_value( self, - value: 'datetime | None', - dialect: 'Dialect' - ) -> 'datetime | None': + value: datetime | None, + dialect: Dialect + ) -> datetime | None: if value is None: return None diff --git a/src/onegov/core/orm/types/uuid_type.py b/src/onegov/core/orm/types/uuid_type.py index 9082e0d595..080b255987 100644 --- a/src/onegov/core/orm/types/uuid_type.py +++ b/src/onegov/core/orm/types/uuid_type.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sqlalchemy.dialects.postgresql import UUID as BaseUUID diff --git a/src/onegov/core/orm/utils.py b/src/onegov/core/orm/utils.py index 81111676ff..f196d32962 100644 --- a/src/onegov/core/orm/utils.py +++ b/src/onegov/core/orm/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sqlalchemy from sqlalchemy_utils import QueryChain as QueryChainBase @@ -13,7 +15,7 @@ # we have to forward declare the implementation, since QueryChainBase # is only generic in our stub and not at runtime class QueryChain(QueryChainBase[_T]): - def slice(self, start: int | None, end: int | None) -> 'Self': ... + def slice(self, start: int | None, end: int | None) -> Self: ... def first(self) -> _T | None: ... def all(self) -> tuple[_T, ...]: ... @@ -21,17 +23,17 @@ def all(self) -> tuple[_T, ...]: ... class QueryChain(QueryChainBase): # type:ignore """ Extends SQLAlchemy Utils' QueryChain with some extra methods. """ - def slice(self, start: int | None, end: int | None) -> 'Self': + def slice(self, start: int | None, end: int | None) -> Self: return self[start:end] - def first(self) -> '_T | None': + def first(self) -> _T | None: return next((o for o in self), None) - def all(self) -> tuple['_T', ...]: + def all(self) -> tuple[_T, ...]: return tuple(self) -def maybe_merge(session: 'Session', obj: '_T') -> '_T': +def maybe_merge(session: Session, obj: _T) -> _T: """ Merges the given obj into the given session, *if* this is possible. That is it acts like more forgiving session.merge(). """ diff --git a/src/onegov/core/redirect.py b/src/onegov/core/redirect.py index c21463faff..338a095e52 100644 --- a/src/onegov/core/redirect.py +++ b/src/onegov/core/redirect.py @@ -13,6 +13,7 @@ class OldPagesRedirect(Redirect): to = '/new-pages """ +from __future__ import annotations from onegov.core import Framework from onegov.core.security import Public @@ -36,5 +37,5 @@ def __init__(self, absorb: str | None = None): @Framework.view(model=Redirect, permission=Public) -def view_redirect(self: Redirect, request: 'CoreRequest') -> 'Response': +def view_redirect(self: Redirect, request: CoreRequest) -> Response: return request.redirect(self.to) diff --git a/src/onegov/core/request.py b/src/onegov/core/request.py index 54481db8a2..aac9a293ed 100644 --- a/src/onegov/core/request.py +++ b/src/onegov/core/request.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import morepath import ua_parser @@ -71,7 +73,7 @@ def role(self) -> str | Column[str]: ... class Message(NamedTuple): text: str - type: 'MessageType' + type: MessageType class ReturnToMixin(_BaseRequest): @@ -124,7 +126,7 @@ def return_to(self, url: str, redirect: str) -> str: def return_here(self, url: str) -> str: return self.return_to(url, self.url) - def redirect(self, url: str) -> 'Response': + def redirect(self, url: str) -> Response: if 'return-to' in self.GET: try: url = self.redirect_signer.loads(self.GET['return-to']) @@ -134,7 +136,7 @@ def redirect(self, url: str) -> 'Response': return morepath.redirect(url) -def is_logged_in(identity: 'Identity | NoIdentity') -> 'TypeGuard[Identity]': +def is_logged_in(identity: Identity | NoIdentity) -> TypeGuard[Identity]: return identity is not NO_IDENTITY @@ -147,19 +149,19 @@ class CoreRequest(IncludeRequest, ContentSecurityRequest, ReturnToMixin): """ - app: 'Framework' + app: Framework @cached_property def identity_secret(self) -> str: return self.app.identity_secret @cached_property - def session(self) -> 'Session': + def session(self) -> Session: return self.app.session() def link_prefix( self, - app: 'Framework | None' = None # type:ignore[override] + app: Framework | None = None # type:ignore[override] ) -> str: """ Override the `link_prefix` with the application base path provided by onegov.server, because the default link_prefix contains the @@ -241,8 +243,8 @@ def link( obj: None, name: str = ..., default: None = ..., - app: 'Framework | Sentinel' = ..., - query_params: 'SupportsItems[str, str] | None' = ..., + app: Framework | Sentinel = ..., + query_params: SupportsItems[str, str] | None = ..., fragment: str | None = ..., ) -> None: ... @@ -252,8 +254,8 @@ def link( obj: None, name: str, default: _T, - app: 'Framework | Sentinel' = ..., - query_params: 'SupportsItems[str, str] | None' = ..., + app: Framework | Sentinel = ..., + query_params: SupportsItems[str, str] | None = ..., fragment: str | None = ..., ) -> _T: ... @@ -263,8 +265,8 @@ def link( obj: object, name: str = ..., default: Any = ..., - app: 'Framework | Sentinel' = ..., - query_params: 'SupportsItems[str, str] | None' = ..., + app: Framework | Sentinel = ..., + query_params: SupportsItems[str, str] | None = ..., fragment: str | None = ..., ) -> str: ... @@ -273,8 +275,8 @@ def link( obj: object, name: str = '', default: _T | None = None, - app: 'Framework | Sentinel' = SAME_APP, - query_params: 'SupportsItems[str, str] | None' = None, + app: Framework | Sentinel = SAME_APP, + query_params: SupportsItems[str, str] | None = None, fragment: str | None = None, ) -> str | _T | None: """ Extends the default link generating function of Morepath. """ @@ -293,7 +295,7 @@ def class_link( model: type[Any], variables: dict[str, Any] | None = None, name: str = '', - app: 'Framework | Sentinel' = SAME_APP, # type:ignore[override] + app: Framework | Sentinel = SAME_APP, # type:ignore[override] ) -> str: """ Extends the default class link generating function of Morepath. """ return self.transform(super().class_link( @@ -349,7 +351,7 @@ def theme_link(self) -> str: return self.link(self.app.modules.theme.ThemeFile(filename)) @cached_property - def browser_session(self) -> 'BrowserSession': + def browser_session(self) -> BrowserSession: """ Returns a browser_session bound to the request. Works via cookies, so requests without cookies won't be able to use the browser_session. @@ -378,7 +380,7 @@ def browser_session(self) -> 'BrowserSession': else: session_id = random_token() - def on_dirty(session: 'BrowserSession', token: str) -> None: + def on_dirty(session: BrowserSession, token: str) -> None: if 'session_id' in self.cookies: return @@ -386,7 +388,7 @@ def on_dirty(session: 'BrowserSession', token: str) -> None: self.cookies['session_id'] = self.app.sign(token) @self.after - def store_session(response: 'morepath.Response') -> None: + def store_session(response: morepath.Response) -> None: response.set_cookie( 'session_id', self.cookies['session_id'], @@ -408,7 +410,7 @@ def get_form( csrf_support: bool = True, data: dict[str, Any] | None = None, model: object = None, - formdata: 'MultiDict[str, str | _FieldStorageWithFile] | None' = None + formdata: MultiDict[str, str | _FieldStorageWithFile] | None = None ) -> _F: """ Returns an instance of the given form class, set up with the correct translator and with CSRF protection enabled (the latter @@ -458,7 +460,7 @@ def get_form( return form @overload - def translate(self, text: 'Markup | TranslationMarkup') -> 'Markup': ... + def translate(self, text: Markup | TranslationMarkup) -> Markup: ... @overload def translate(self, text: str) -> str: ... @@ -477,7 +479,7 @@ def translate(self, text: str) -> str: return self.translator(text) @cached_property - def translator(self) -> 'Callable[[str], str]': + def translator(self) -> Callable[[str], str]: """ Returns the translate function for basic string translations. """ translator = self.get_translate() @@ -512,19 +514,19 @@ def html_lang(self) -> str: @overload def get_translate( self, - for_chameleon: 'Literal[False]' = False - ) -> 'GNUTranslations | None': ... + for_chameleon: Literal[False] = False + ) -> GNUTranslations | None: ... @overload def get_translate( self, - for_chameleon: 'Literal[True]' - ) -> '_ChameleonTranslate | None': ... + for_chameleon: Literal[True] + ) -> _ChameleonTranslate | None: ... def get_translate( self, for_chameleon: bool = False - ) -> 'GNUTranslations | _ChameleonTranslate | None': + ) -> GNUTranslations | _ChameleonTranslate | None: """ Returns the translate method to the given request, or None if no such method is availabe. @@ -546,7 +548,7 @@ def get_translate( else: return self.app.translations.get(locale) - def message(self, text: str, type: 'MessageType') -> None: + def message(self, text: str, type: MessageType) -> None: """ Adds a message with the given type to the messages list. This messages list may then be displayed by an application building on onegov.core. @@ -576,7 +578,7 @@ def message(self, text: str, type: 'MessageType') -> None: Message(text, type) ] - def consume_messages(self) -> 'Iterator[Message]': + def consume_messages(self) -> Iterator[Message]: """ Returns the messages, removing them from the session in the process. Call only if you can be reasonably sure that the user will see the messages. @@ -613,8 +615,8 @@ def agent(self) -> ua_parser.DefaultedResult: def has_permission( self, model: object, - permission: type['Intent'] | None, - user: 'UserLike | None' = None + permission: type[Intent] | None, + user: UserLike | None = None ) -> bool: """ Returns True if the current or given user has the given permission on the given model. @@ -654,7 +656,7 @@ def has_access_to_url(self, url: str) -> bool: permission = self.app.permission_by_view(obj, view_name) return self.has_permission(obj, permission) - def exclude_invisible(self, models: 'Iterable[_T]') -> list[_T]: + def exclude_invisible(self, models: Iterable[_T]) -> list[_T]: """ Excludes models invisble to the current user from the list. """ return [m for m in models if self.is_visible(m)] @@ -819,7 +821,7 @@ def load_url_safe_token( return None @cached_property - def template_loader(self) -> 'TemplateLoader': + def template_loader(self) -> TemplateLoader: """ Returns the chameleon template loader. """ registry = self.app.config.template_engine_registry return registry._template_loaders['.pt'] diff --git a/src/onegov/core/security/__init__.py b/src/onegov/core/security/__init__.py index 9c712c9d72..34c4df1e3e 100644 --- a/src/onegov/core/security/__init__.py +++ b/src/onegov/core/security/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security.identity_policy import forget from onegov.core.security.identity_policy import remembered from onegov.core.security.permissions import Personal diff --git a/src/onegov/core/security/identity_policy.py b/src/onegov/core/security/identity_policy.py index e021ef16ba..b5a68bb09e 100644 --- a/src/onegov/core/security/identity_policy.py +++ b/src/onegov/core/security/identity_policy.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import Identity from onegov.core.browser_session import BrowserSession from onegov.core.framework import Framework @@ -16,7 +18,7 @@ class IdentityPolicy: required_keys = {'userid', 'groupid', 'role', 'application_id'} - def identify(self, request: 'CoreRequest') -> Identity | None: + def identify(self, request: CoreRequest) -> Identity | None: try: identifiers = { key: request.browser_session[key] for key in self.required_keys @@ -29,14 +31,14 @@ def identify(self, request: 'CoreRequest') -> Identity | None: def remember( self, - response: 'Response', - request: 'CoreRequest', + response: Response, + request: CoreRequest, identity: Identity ) -> None: for key in self.required_keys: request.browser_session[key] = getattr(identity, key) - def forget(self, response: 'Response', request: 'CoreRequest') -> None: + def forget(self, response: Response, request: CoreRequest) -> None: request.browser_session.flush() diff --git a/src/onegov/core/security/permissions.py b/src/onegov/core/security/permissions.py index 27a080d484..fbd5b3a375 100644 --- a/src/onegov/core/security/permissions.py +++ b/src/onegov/core/security/permissions.py @@ -6,6 +6,7 @@ may of course introduce its own byzantine permission system. """ +from __future__ import annotations class Intent: diff --git a/src/onegov/core/security/roles.py b/src/onegov/core/security/roles.py index 93ae112b6c..97f25b839e 100644 --- a/src/onegov/core/security/roles.py +++ b/src/onegov/core/security/roles.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.framework import Framework from onegov.core.security import Public, Personal, Private, Secret @@ -8,7 +10,7 @@ @Framework.setting_section(section='roles') -def get_roles_setting() -> dict[str, set[type['Intent']]]: +def get_roles_setting() -> dict[str, set[type[Intent]]]: """ Returns the default roles available to onegov.core applications. Applications building on onegov.core may add more roles and permissions, diff --git a/src/onegov/core/security/rules.py b/src/onegov/core/security/rules.py index 806366cb65..e643bbf827 100644 --- a/src/onegov/core/security/rules.py +++ b/src/onegov/core/security/rules.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.cronjobs import Job from onegov.core.framework import Framework from onegov.core.security import Public @@ -39,7 +41,7 @@ def has_permission_not_logged_in( @Framework.permission_rule(model=object, permission=object) def has_permission_logged_in( app: Framework, - identity: 'HasRole', + identity: HasRole, model: object, permission: object ) -> bool: diff --git a/src/onegov/core/sentry.py b/src/onegov/core/sentry.py index 267bf4f429..735442a059 100644 --- a/src/onegov/core/sentry.py +++ b/src/onegov/core/sentry.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os import sys import weakref @@ -60,10 +62,10 @@ def setup_once() -> None: @Framework.tween_factory(over=excview_tween_factory) def sentry_tween_factory( app: Framework, - handler: 'Callable[[CoreRequest], Response]' - ) -> 'Callable[[CoreRequest], Response]': + handler: Callable[[CoreRequest], Response] + ) -> Callable[[CoreRequest], Response]: - def sentry_tween(request: 'CoreRequest') -> 'Response': + def sentry_tween(request: CoreRequest) -> Response: """ Configures scope and starts transaction """ integration = get_client().get_integration( @@ -110,12 +112,12 @@ def with_sentry_middleware(self: Framework) -> bool: class CoreRequestExtractor(RequestExtractor): - request: 'CoreRequest' + request: CoreRequest - def env(self) -> 'WSGIEnvironment': + def env(self) -> WSGIEnvironment: return self.request.environ - def cookies(self) -> 'RequestCookies': + def cookies(self) -> RequestCookies: return self.request.cookies def raw_data(self) -> str: @@ -128,14 +130,14 @@ def form(self) -> dict[str, str]: if isinstance(value, str) } - def files(self) -> dict[str, '_FieldStorageWithFile']: + def files(self) -> dict[str, _FieldStorageWithFile]: return { key: value for key, value in self.request.POST.items() if not isinstance(value, str) } - def size_of_file(self, postdata: '_FieldStorageWithFile') -> int: + def size_of_file(self, postdata: _FieldStorageWithFile) -> int: file = postdata.file try: return os.fstat(file.fileno()).st_size @@ -143,7 +145,7 @@ def size_of_file(self, postdata: '_FieldStorageWithFile') -> int: return 0 -def _capture_exception(exc_info: 'ExcInfo') -> None: +def _capture_exception(exc_info: ExcInfo) -> None: if exc_info[0] is None or issubclass(exc_info[0], HTTPException): return @@ -157,10 +159,10 @@ def _capture_exception(exc_info: 'ExcInfo') -> None: def _make_event_processor( - weak_request: 'Callable[[], CoreRequest | None]', + weak_request: Callable[[], CoreRequest | None], integration: OneGovCloudIntegration, -) -> 'EventProcessor': - def event_processor(event: 'Event', hint: 'Hint') -> 'Event': +) -> EventProcessor: + def event_processor(event: Event, hint: Hint) -> Event: request = weak_request() if request is None: return event diff --git a/src/onegov/core/sms_processor.py b/src/onegov/core/sms_processor.py index 1f3348d647..9356b114bb 100644 --- a/src/onegov/core/sms_processor.py +++ b/src/onegov/core/sms_processor.py @@ -7,6 +7,7 @@ qp = SmsQueueProcessor(sms_directory) qp.send_messages() """ +from __future__ import annotations import errno import logging @@ -163,7 +164,7 @@ def message_files(self) -> tuple[str, ...]: def send( self, - numbers: 'Sequence[str]', + numbers: Sequence[str], content: str ) -> dict[str, Any] | None: """ Sends the SMS and returns the API response on error. @@ -187,7 +188,7 @@ def send( return result return None - def send_request(self, parameters: 'JSON_ro') -> tuple[int, str]: + def send_request(self, parameters: JSON_ro) -> tuple[int, str]: """ Performes the API request using the given parameters. """ body = BytesIO() @@ -368,7 +369,7 @@ def send_message(self, filename: str) -> None: def get_sms_queue_processor( - app: 'Framework', + app: Framework, missing_path_ok: bool = False ) -> SmsQueueProcessor | None: diff --git a/src/onegov/core/static.py b/src/onegov/core/static.py index d3590ccbd2..c13bd43a62 100644 --- a/src/onegov/core/static.py +++ b/src/onegov/core/static.py @@ -30,6 +30,7 @@ def get_favicon(app, absorb): return StaticFile.from_application(app, 'favicon.ico') """ +from __future__ import annotations import os.path @@ -64,7 +65,7 @@ def absorb(self) -> str: return self.path @classmethod - def from_application(cls, app: Framework, absorb: str) -> 'Self | None': + def from_application(cls, app: Framework, absorb: str) -> Self | None: """ Absorbs all /static/* paths and returns :class:`StaticFile` instances with the path set to a subpath of :meth:`onegov.core.Framework.static_files`. @@ -107,13 +108,13 @@ def get_static_file(app: Framework, absorb: str) -> StaticFile | None: @Framework.view(model=StaticFile, render=render_file, permission=Public) -def view_static_file(self: StaticFile, request: 'CoreRequest') -> str | None: +def view_static_file(self: StaticFile, request: CoreRequest) -> str | None: """ Renders the given static file in the browser. """ if self.version: @request.after - def cache_forever(response: 'Response') -> None: + def cache_forever(response: Response) -> None: response.headers['Cache-Control'] = 'max-age=31536000' for directory in request.app.static_files: diff --git a/src/onegov/core/templates.py b/src/onegov/core/templates.py index 047df4a7c9..729d0af1b3 100644 --- a/src/onegov/core/templates.py +++ b/src/onegov/core/templates.py @@ -32,6 +32,7 @@ def view_root(self, request): path. """ +from __future__ import annotations import os.path @@ -97,8 +98,8 @@ def __init__(self, *args: Any, **kwargs: Any): def get_default_vars( - request: 'CoreRequest', - content: 'Mapping[str, Any]', + request: CoreRequest, + content: Mapping[str, Any], suppress_global_variables: bool = False ) -> dict[str, Any]: @@ -130,11 +131,11 @@ class TemplateLoader(PageTemplateLoader): } @cached_property - def macros(self) -> 'MacrosLookup': + def macros(self) -> MacrosLookup: return MacrosLookup(self.search_path, name='macros.pt') @cached_property - def mail_macros(self) -> 'MacrosLookup': + def mail_macros(self) -> MacrosLookup: return MacrosLookup(self.search_path, name='mail_macros.pt') @@ -158,7 +159,7 @@ class MacrosLookup: def __init__( self, - search_paths: 'Iterable[StrPath]', + search_paths: Iterable[StrPath], name: str = 'macros.pt' ): paths = (os.path.join(base, name) for base in search_paths) @@ -178,7 +179,7 @@ def __init__( for name in template.macros.names } - def __getitem__(self, name: str) -> 'Macro': + def __getitem__(self, name: str) -> Macro: # macro names in chameleon are normalized internally and we need # to do the same to get the correct name in any case: name = name.replace('-', '_') @@ -207,14 +208,14 @@ def get_template_loader( def get_chameleon_render( loader: TemplateLoader, name: str, - original_render: 'Callable[[str, CoreRequest], _T]' -) -> 'Callable[[dict[str, Any], CoreRequest], _T]': + original_render: Callable[[str, CoreRequest], _T] +) -> Callable[[dict[str, Any], CoreRequest], _T]: """ Returns the Chameleon template renderer for the required template. """ template = loader.load(name, 'xml') - def render(content: dict[str, Any], request: 'CoreRequest') -> Any: + def render(content: dict[str, Any], request: CoreRequest) -> Any: variables = get_default_vars(request, content) return original_render(template.render(**variables), request) @@ -224,7 +225,7 @@ def render(content: dict[str, Any], request: 'CoreRequest') -> Any: def render_template( template: str, - request: 'CoreRequest', + request: CoreRequest, content: dict[str, Any], suppress_global_variables: bool | Literal['infer'] = 'infer' ) -> Markup: @@ -250,8 +251,8 @@ def render_template( def render_macro( - macro: 'Macro', - request: 'CoreRequest', + macro: Macro, + request: CoreRequest, content: dict[str, Any], suppress_global_variables: bool = True ) -> Markup: diff --git a/src/onegov/core/theme.py b/src/onegov/core/theme.py index 9831c5eda0..6d9701c7be 100644 --- a/src/onegov/core/theme.py +++ b/src/onegov/core/theme.py @@ -40,6 +40,7 @@ def theme_options(self): Note that for the theme to work you need to define a filestorage. See :meth:`onegov.core.framework.Framework.configure_application`. """ +from __future__ import annotations from onegov.core import __version__ from onegov.core.framework import Framework @@ -105,7 +106,7 @@ def get_filename(theme: Theme, options: dict[str, Any] | None = None) -> str: def compile( - storage: 'FS | SubFS[FS]', + storage: FS | SubFS[FS], theme: Theme, options: dict[str, Any] | None = None, force: bool = False diff --git a/src/onegov/core/types.py b/src/onegov/core/types.py index 3b159d7b34..186e8da935 100644 --- a/src/onegov/core/types.py +++ b/src/onegov/core/types.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import TYPE_CHECKING if TYPE_CHECKING: from typing import ( diff --git a/src/onegov/core/upgrade.py b/src/onegov/core/upgrade.py index 42d5c0317b..9e6b994a63 100644 --- a/src/onegov/core/upgrade.py +++ b/src/onegov/core/upgrade.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import inspect import importlib import pkg_resources @@ -71,10 +73,10 @@ def executed_tasks(self) -> set[str]: else: return set(self.state.get('executed_tasks', [])) - def was_already_executed(self, task: '_Task[..., Any]') -> bool: + def was_already_executed(self, task: _Task[..., Any]) -> bool: return task.task_name in self.executed_tasks - def mark_as_executed(self, task: '_Task[..., Any]') -> None: + def mark_as_executed(self, task: _Task[..., Any]) -> None: if not self.state: self.state = {} @@ -90,7 +92,7 @@ def mark_as_executed(self, task: '_Task[..., Any]') -> None: def get_distributions_with_entry_map( key: str -) -> 'Iterator[tuple[Distribution, dict[str, EntryPoint]]]': +) -> Iterator[tuple[Distribution, dict[str, EntryPoint]]]: """ Iterates through all distributions with entry_maps and yields each distribution along side the entry map with the given key. @@ -103,7 +105,7 @@ def get_distributions_with_entry_map( yield distribution, entry_map -def get_upgrade_modules() -> 'Iterator[tuple[str, ModuleType]]': +def get_upgrade_modules() -> Iterator[tuple[str, ModuleType]]: """ Returns all modules that registered themselves for onegov.core upgrades like this:: @@ -233,11 +235,11 @@ def __init__( # NOTE: We only allow the two supported function signatures @overload - def __call__(self, fn: 'UpgradeFunc') -> 'UpgradeTask': ... + def __call__(self, fn: UpgradeFunc) -> UpgradeTask: ... @overload - def __call__(self, fn: 'RawFunc') -> 'RawTask': ... + def __call__(self, fn: RawFunc) -> RawTask: ... - def __call__(self, fn: 'Callable[_P, _T]') -> '_Task[_P, _T]': + def __call__(self, fn: Callable[_P, _T]) -> _Task[_P, _T]: fn = cast('_Task[_P, _T]', fn) fn.task_name = self.name fn.always_run = self.always_run @@ -246,7 +248,7 @@ def __call__(self, fn: 'Callable[_P, _T]') -> '_Task[_P, _T]': return fn -def is_task(function: 'Callable[_P, _T]') -> 'TypeGuard[_Task[_P, _T]]': +def is_task(function: Callable[_P, _T]) -> TypeGuard[_Task[_P, _T]]: """ Returns True if the given function is an uprade task. """ if not (isfunction(function) or ismethod(function)): return False @@ -254,15 +256,15 @@ def is_task(function: 'Callable[_P, _T]') -> 'TypeGuard[_Task[_P, _T]]': return hasattr(function, 'task_name') -def get_module_tasks(module: 'ModuleType') -> 'Iterator[_Task[..., Any]]': +def get_module_tasks(module: ModuleType) -> Iterator[_Task[..., Any]]: """ Goes through a module or class and returns all upgrade tasks. """ for name, function in getmembers(module, is_task): yield function def get_tasks_by_id( - upgrade_modules: 'Iterable[tuple[str, ModuleType]]' -) -> dict[str, '_Task[..., Any]']: + upgrade_modules: Iterable[tuple[str, ModuleType]] +) -> dict[str, _Task[..., Any]]: """ Takes a list of upgrade modules or classes and returns the tasks keyed by id. @@ -290,8 +292,8 @@ def get_tasks_by_id( def get_module_order_key( - tasks: 'Mapping[str, _Task[..., Any]]' -) -> 'Callable[[str], SupportsRichComparison]': + tasks: Mapping[str, _Task[..., Any]] +) -> Callable[[str], SupportsRichComparison]: """ Returns a sort order key which orders task_ids in order of their module dependencies. That is a task from onegov.core is sorted before a task in onegov.user, because onegov.user depends on onegov.core. @@ -305,7 +307,7 @@ def get_module_order_key( for task in tasks: modules.add(task.split(':', 1)[0]) - def sortkey(task: str) -> 'SupportsRichComparison': + def sortkey(task: str) -> SupportsRichComparison: module = task.split(':', 1)[0] return ( # sort by level (unknown models first) @@ -322,8 +324,8 @@ def sortkey(task: str) -> 'SupportsRichComparison': def get_tasks( - upgrade_modules: 'Iterable[tuple[str, ModuleType]] | None' = None -) -> list[tuple[str, '_Task[..., Any]']]: + upgrade_modules: Iterable[tuple[str, ModuleType]] | None = None +) -> list[tuple[str, _Task[..., Any]]]: """ Takes a list of upgrade modules or classes and returns the tasks that should be run in the order they should be run. @@ -356,9 +358,9 @@ def get_tasks( def register_modules( - session: 'Session', - modules: 'Iterable[tuple[str, ModuleType]]', - tasks: 'Collection[tuple[str, _Task[..., Any]]]' + session: Session, + modules: Iterable[tuple[str, ModuleType]], + tasks: Collection[tuple[str, _Task[..., Any]]] ) -> None: """ Sets up the state tracking for all modules. Initially, all tasks are marekd as executed, because we assume tasks to upgrade older @@ -393,7 +395,7 @@ def register_modules( session.flush() -def register_all_modules_and_tasks(session: 'Session') -> None: +def register_all_modules_and_tasks(session: Session) -> None: """ Registers all the modules and all the tasks. """ register_modules(session, get_upgrade_modules(), get_tasks()) @@ -407,7 +409,7 @@ class UpgradeTransaction: """ - def __init__(self, context: 'UpgradeContext'): + def __init__(self, context: UpgradeContext): self.operations_transaction = context.operations_connection.begin() self.session = context.session @@ -434,7 +436,7 @@ class UpgradeContext: # to be auto-generated as well, so we get the available methods operations: Any - def __init__(self, request: 'CoreRequest'): + def __init__(self, request: CoreRequest): # alembic is a somewhat heavy import (thanks to the integrated mako) # -> since we really only ever need it during upgrades we lazy load @@ -496,7 +498,7 @@ def has_table(self, table: str) -> bool: inspector = Inspector(self.operations_connection) return table in inspector.get_table_names(schema=self.schema) - def models(self, table: str) -> 'Iterator[Any]': + def models(self, table: str) -> Iterator[Any]: def has_matching_tablename(model: Any) -> bool: if not hasattr(model, '__tablename__'): return False # abstract bases @@ -509,23 +511,23 @@ def has_matching_tablename(model: Any) -> bool: def records_per_table( self, table: str, - columns: 'Iterable[Column[Any]] | None' = None - ) -> 'Iterator[Any]': + columns: Iterable[Column[Any]] | None = None + ) -> Iterator[Any]: if columns is None: - def filter_columns(q: 'Query[Any]') -> 'Query[Any]': + def filter_columns(q: Query[Any]) -> Query[Any]: return q else: column_names = tuple(c.name for c in columns) - def filter_columns(q: 'Query[Any]') -> 'Query[Any]': + def filter_columns(q: Query[Any]) -> Query[Any]: return q.options(load_only(*column_names)) for model in self.models(table): yield from filter_columns(self.session.query(model)) @contextmanager - def stop_search_updates(self) -> 'Iterator[None]': + def stop_search_updates(self) -> Iterator[None]: # XXX this would be better handled with a more general approach # that doesn't require knowledge of onegov.search if hasattr(self.app, 'es_orm_events'): @@ -542,8 +544,8 @@ def is_empty_table(self, table: str) -> bool: def add_column_with_defaults( self, table: str, - column: 'Column[_T]', - default: '_T | Callable[[Any], _T]' + column: Column[_T], + default: _T | Callable[[Any], _T] ) -> None: # XXX while adding default values we shouldn't reindex the data # since this is what the default add_column code does and will be @@ -583,10 +585,10 @@ class RawUpgradeRunner: def __init__( self, - tasks: 'Sequence[tuple[str, RawTask]]', + tasks: Sequence[tuple[str, RawTask]], commit: bool = True, - on_task_success: 'TaskCallback | None' = None, - on_task_fail: 'TaskCallback | None' = None + on_task_success: TaskCallback | None = None, + on_task_fail: TaskCallback | None = None ): self.tasks = tasks self.commit = commit @@ -599,7 +601,7 @@ def __init__( self._on_task_success = on_task_success self._on_task_fail = on_task_fail - def run_upgrade(self, dsn: str, schemas: 'Sequence[str]') -> int: + def run_upgrade(self, dsn: str, schemas: Sequence[str]) -> int: # it's possible for applications to exist without schemas, if the # application doesn't use multi-tennants and has not been run yet @@ -654,11 +656,11 @@ class UpgradeRunner: def __init__( self, - modules: 'Sequence[tuple[str, ModuleType]]', - tasks: 'Sequence[tuple[str, UpgradeTask]]', + modules: Sequence[tuple[str, ModuleType]], + tasks: Sequence[tuple[str, UpgradeTask]], commit: bool = True, - on_task_success: 'TaskCallback | None' = None, - on_task_fail: 'TaskCallback | None' = None + on_task_success: TaskCallback | None = None, + on_task_fail: TaskCallback | None = None ): self.modules = modules self.tasks = tasks @@ -668,11 +670,11 @@ def __init__( self._on_task_success = on_task_success self._on_task_fail = on_task_fail - def on_task_success(self, task: 'UpgradeTask') -> None: + def on_task_success(self, task: UpgradeTask) -> None: if self._on_task_success is not None: self._on_task_success(task) - def on_task_fail(self, task: 'UpgradeTask') -> None: + def on_task_fail(self, task: UpgradeTask) -> None: if self._on_task_fail is not None: self._on_task_fail(task) @@ -686,7 +688,7 @@ def get_state(self, context: UpgradeContext, module: str) -> UpgradeState: return context.session.merge(self.states[module], load=True) - def register_modules(self, request: 'CoreRequest') -> None: + def register_modules(self, request: CoreRequest) -> None: register_modules(request.session, self.modules, self.tasks) if self.commit: @@ -695,7 +697,7 @@ def register_modules(self, request: 'CoreRequest') -> None: def get_module_from_task_id(self, task_id: str) -> str: return task_id.split(':', 1)[0] - def run_upgrade(self, request: 'CoreRequest') -> int: + def run_upgrade(self, request: CoreRequest) -> int: self.register_modules(request) tasks = ((self.get_module_from_task_id(i), t) for i, t in self.tasks) diff --git a/src/onegov/core/upgrades.py b/src/onegov/core/upgrades.py index 361a87938c..175d9ff5cd 100644 --- a/src/onegov/core/upgrades.py +++ b/src/onegov/core/upgrades.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + from itertools import chain from libres.db.models import ORMBase from onegov.core.upgrade import upgrade_task @@ -23,7 +25,7 @@ @upgrade_task('Drop primary key from associated tables') -def drop_primary_key_from_associated_tables(context: 'UpgradeContext') -> None: +def drop_primary_key_from_associated_tables(context: UpgradeContext) -> None: bases = set() for cls in find_models(Base, lambda cls: issubclass(cls, Associable)): @@ -43,12 +45,12 @@ def drop_primary_key_from_associated_tables(context: 'UpgradeContext') -> None: @upgrade_task('Migrate to JSONB', always_run=True, raw=True) def migrate_to_jsonb( - connection: 'Connection', - schemas: 'Sequence[str]' -) -> 'Iterator[bool]': + connection: Connection, + schemas: Sequence[str] +) -> Iterator[bool]: """ Migrates all text base json columns to jsonb. """ - def json_columns(cls: type[Any]) -> 'Iterator[Column[Any]]': + def json_columns(cls: type[Any]) -> Iterator[Column[Any]]: try: for column in inspect(cls).columns: if isinstance(column.type, JSON): @@ -112,7 +114,7 @@ def json_columns(cls: type[Any]) -> 'Iterator[Column[Any]]': @upgrade_task('Rename associated tables') -def rename_associated_tables(context: 'UpgradeContext') -> None: +def rename_associated_tables(context: UpgradeContext) -> None: bases = set() for cls in find_models(Base, lambda cls: issubclass(cls, Associable)): @@ -142,7 +144,7 @@ def rename_associated_tables(context: 'UpgradeContext') -> None: @upgrade_task('OGC-1792 Remove all wtfs tables') -def remove_all_wtfs_tables(context: 'UpgradeContext') -> None: +def remove_all_wtfs_tables(context: UpgradeContext) -> None: tables = ['wtfs_payment_type', 'wtfs_pickup_dates', 'wtfs_scan_jobs'] for table in tables: @@ -152,7 +154,7 @@ def remove_all_wtfs_tables(context: 'UpgradeContext') -> None: @upgrade_task('Remove redundant page to general file links') def remove_redundant_page_to_general_file_links( - context: 'UpgradeContext' + context: UpgradeContext ) -> None: if not context.has_table('files_for_pages_files'): @@ -189,7 +191,7 @@ def remove_redundant_page_to_general_file_links( @upgrade_task('Add unique constraint to association tables') -def unique_constraint_in_association_tables(context: 'UpgradeContext') -> None: +def unique_constraint_in_association_tables(context: UpgradeContext) -> None: bases = set() for cls in chain( diff --git a/src/onegov/core/utils.py b/src/onegov/core/utils.py index 9c83b9144c..a2197983a1 100644 --- a/src/onegov/core/utils.py +++ b/src/onegov/core/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import base64 import bleach from urlextract import URLExtract, CacheFileError @@ -96,7 +98,7 @@ @contextmanager -def local_lock(namespace: str, key: str) -> 'Iterator[None]': +def local_lock(namespace: str, key: str) -> Iterator[None]: """ Locks the given namespace/key combination on the current system, automatically freeing it after the with statement has been completed or once the process is killed. @@ -172,7 +174,7 @@ def remove_repeated_spaces(text: str) -> str: @contextmanager -def profile(filename: str) -> 'Iterator[None]': +def profile(filename: str) -> Iterator[None]: """ Profiles the wrapped code and stores the result in the profiles folder with the given filename. @@ -188,7 +190,7 @@ def profile(filename: str) -> 'Iterator[None]': @contextmanager -def timing(name: str | None = None) -> 'Iterator[None]': +def timing(name: str | None = None) -> Iterator[None]: """ Runs the wrapped code and prints the time in ms it took to run it. The name is printed in front of the time, if given. @@ -206,7 +208,7 @@ def timing(name: str | None = None) -> 'Iterator[None]': @lru_cache(maxsize=32) -def module_path_root(module: 'ModuleType | str') -> str: +def module_path_root(module: ModuleType | str) -> str: if isinstance(module, str): module = importlib.import_module(module) @@ -215,7 +217,7 @@ def module_path_root(module: 'ModuleType | str') -> str: return os.path.dirname(inspect.getfile(module)) -def module_path(module: 'ModuleType | str', subpath: str) -> str: +def module_path(module: ModuleType | str, subpath: str) -> str: """ Returns a subdirectory in the given python module. :mod: @@ -289,7 +291,7 @@ def __ne__(self, other: object) -> bool: return not self.__eq__(other) -def render_file(file_path: str, request: 'CoreRequest') -> 'Response': +def render_file(file_path: str, request: CoreRequest) -> Response: """ Takes the given file_path (content) and renders it to the browser. The file must exist on the local system and be readable by the current process. @@ -347,13 +349,13 @@ def groupbylist( @overload def groupbylist( iterable: Iterable[_T], - key: 'Callable[[_T], _KT]' + key: Callable[[_T], _KT] ) -> list[tuple[_KT, list[_T]]]: ... def groupbylist( iterable: Iterable[_T], - key: 'Callable[[_T], Any] | None' = None + key: Callable[[_T], Any] | None = None ) -> list[tuple[Any, list[_T]]]: """ Works just like Python's ``itertools.groupby`` function, but instead of returning generators, it returns lists. @@ -384,7 +386,7 @@ def is_valid_length(number: str) -> bool: return len(number) == 12 return False - def handle_match(match: 'Match[str]') -> str: + def handle_match(match: Match[str]) -> str: inside_html = match.group(1) number = f'{match.group(2)}{match.group(3)}' assert not number.endswith('\n') @@ -648,16 +650,16 @@ def is_subpath(directory: str, path: str) -> bool: @overload def is_sorted( - iterable: 'Iterable[SupportsRichComparison]', - key: 'Callable[[SupportsRichComparison], SupportsRichComparison]' = ..., + iterable: Iterable[SupportsRichComparison], + key: Callable[[SupportsRichComparison], SupportsRichComparison] = ..., reverse: bool = ... ) -> bool: ... @overload def is_sorted( - iterable: 'Iterable[_T]', - key: 'Callable[[_T], SupportsRichComparison]', + iterable: Iterable[_T], + key: Callable[[_T], SupportsRichComparison], reverse: bool = ... ) -> bool: ... @@ -667,8 +669,8 @@ def is_sorted( # be infinite. This seems like it should be a Container instead, # then we also don't need to use tee or list to make a copy def is_sorted( - iterable: 'Iterable[Any]', - key: 'Callable[[Any], SupportsRichComparison]' = lambda i: i, + iterable: Iterable[Any], + key: Callable[[Any], SupportsRichComparison] = lambda i: i, reverse: bool = False ) -> bool: """ Returns True if the iterable is sorted. """ @@ -685,7 +687,7 @@ def is_sorted( return True -def morepath_modules(cls: type[morepath.App]) -> 'Iterator[str]': +def morepath_modules(cls: type[morepath.App]) -> Iterator[str]: """ Returns all morepath modules which should be scanned for the given morepath application class. @@ -720,8 +722,8 @@ def scan_morepath_modules(cls: type[morepath.App]) -> None: def get_unique_hstore_keys( - session: 'Session', - column: 'Column[dict[str, Any]]' + session: Session, + column: Column[dict[str, Any]] ) -> set[str]: """ Returns a set of keys found in an hstore column over all records of its table. @@ -740,7 +742,7 @@ def get_unique_hstore_keys( return set(keys) if keys else set() -def makeopendir(fs: 'FS', directory: str) -> 'SubFS[FS]': +def makeopendir(fs: FS, directory: str) -> SubFS[FS]: """ Creates and opens the given directory in the given PyFilesystem. """ if not fs.isdir(directory): @@ -786,7 +788,7 @@ def __init__( self, url: str, data: bytes, - headers: 'Collection[tuple[str, str]]', + headers: Collection[tuple[str, str]], timeout: float = 30 ): Thread.__init__(self) @@ -831,7 +833,7 @@ def toggle(collection: set[_T], item: _T | None) -> set[_T]: def binary_to_dictionary( binary: bytes, filename: str | None = None -) -> 'FileDict': +) -> FileDict: """ Takes raw binary filedata and stores it in a dictionary together with metadata information. @@ -861,7 +863,7 @@ def binary_to_dictionary( } -def dictionary_to_binary(dictionary: 'LaxFileDict') -> bytes: +def dictionary_to_binary(dictionary: LaxFileDict) -> bytes: """ Takes a dictionary created by :func:`binary_to_dictionary` and returns the original binary data. @@ -877,7 +879,7 @@ def safe_format( format: str, dictionary: dict[str, str | int | float], types: None = ..., - adapt: 'Callable[[str], str] | None' = ..., + adapt: Callable[[str], str] | None = ..., raise_on_missing: bool = ... ) -> str: ... @@ -887,7 +889,7 @@ def safe_format( format: str, dictionary: dict[str, _T], types: set[type[_T]] = ..., - adapt: 'Callable[[str], str] | None' = ..., + adapt: Callable[[str], str] | None = ..., raise_on_missing: bool = ... ) -> str: ... @@ -896,7 +898,7 @@ def safe_format( format: str, dictionary: dict[str, Any], types: set[type[Any]] | None = None, - adapt: 'Callable[[str], str] | None' = None, + adapt: Callable[[str], str] | None = None, raise_on_missing: bool = False ) -> str: """ Takes a user-supplied string with format blocks and returns a string @@ -987,7 +989,7 @@ def safe_format( def safe_format_keys( format: str, - adapt: 'Callable[[str], str] | None' = None + adapt: Callable[[str], str] | None = None ) -> list[str]: """ Takes a :func:`safe_format` string and returns the found keys. """ @@ -1175,16 +1177,16 @@ def safe_move(src: str, dst: str, tmp_dst: str | None = None) -> None: def batched( iterable: Iterable[_T], batch_size: int, - container_factory: 'type[tuple]' = ... # type:ignore[type-arg] -) -> 'Iterator[tuple[_T, ...]]': ... + container_factory: type[tuple] = ... # type:ignore[type-arg] +) -> Iterator[tuple[_T, ...]]: ... @overload def batched( iterable: Iterable[_T], batch_size: int, - container_factory: 'type[list]' # type:ignore[type-arg] -) -> 'Iterator[list[_T]]': ... + container_factory: type[list] # type:ignore[type-arg] +) -> Iterator[list[_T]]: ... # NOTE: If there were higher order TypeVars, we could properly infer @@ -1194,15 +1196,15 @@ def batched( def batched( iterable: Iterable[_T], batch_size: int, - container_factory: 'Callable[[Iterator[_T]], Collection[_T]]' -) -> 'Iterator[Collection[_T]]': ... + container_factory: Callable[[Iterator[_T]], Collection[_T]] +) -> Iterator[Collection[_T]]: ... def batched( iterable: Iterable[_T], batch_size: int, - container_factory: 'Callable[[Iterator[_T]], Collection[_T]]' = tuple -) -> 'Iterator[Collection[_T]]': + container_factory: Callable[[Iterator[_T]], Collection[_T]] = tuple +) -> Iterator[Collection[_T]]: """ Splits an iterable into batches of batch_size and puts them inside a given collection (tuple by default). diff --git a/src/onegov/core/widgets.py b/src/onegov/core/widgets.py index 0f691a4f68..cad450a08b 100644 --- a/src/onegov/core/widgets.py +++ b/src/onegov/core/widgets.py @@ -30,6 +30,7 @@ def get_variables(self, layout): template.render(**inject_variables(widgets, layout, structure)) """ +from __future__ import annotations from lxml import etree from wtforms.validators import ValidationError @@ -94,9 +95,9 @@ def template(self) -> str: ... def parse_structure( - widgets: 'Collection[Widget]', + widgets: Collection[Widget], structure: str -) -> 'etree._Element': +) -> etree._Element: """ Takes the XML structure and returns the parsed etree xml. Raises a wtforms.ValidationError if there's an element which is not @@ -141,7 +142,7 @@ def parse_structure( return xml_tree -def transform_structure(widgets: 'Collection[Widget]', structure: str) -> str: +def transform_structure(widgets: Collection[Widget], structure: str) -> str: """ Takes the XML structure and transforms it into a chameleon template. The app is required as it contains the available widgets. @@ -158,8 +159,8 @@ def transform_structure(widgets: 'Collection[Widget]', structure: str) -> str: @overload def inject_variables( - widgets: 'Collection[Widget]', - layout: 'Layout', + widgets: Collection[Widget], + layout: Layout, structure: Literal[''] | None, variables: None = None, unique_variable_names: bool = True @@ -168,41 +169,41 @@ def inject_variables( @overload def inject_variables( - widgets: 'Collection[Widget]', - layout: 'Layout', + widgets: Collection[Widget], + layout: Layout, structure: Literal[''] | None, - variables: 'RenderData', + variables: RenderData, unique_variable_names: bool = True -) -> 'RenderData': ... +) -> RenderData: ... @overload def inject_variables( - widgets: 'Collection[Widget]', - layout: 'Layout', + widgets: Collection[Widget], + layout: Layout, structure: str, variables: None = None, unique_variable_names: bool = True -) -> 'RenderData | None': ... +) -> RenderData | None: ... @overload def inject_variables( - widgets: 'Collection[Widget]', - layout: 'Layout', + widgets: Collection[Widget], + layout: Layout, structure: str | None, - variables: 'RenderData', + variables: RenderData, unique_variable_names: bool = True -) -> 'RenderData': ... +) -> RenderData: ... def inject_variables( - widgets: 'Collection[Widget]', - layout: 'Layout', + widgets: Collection[Widget], + layout: Layout, structure: str | None, - variables: 'RenderData | None' = None, + variables: RenderData | None = None, unique_variable_names: bool = True -) -> 'RenderData | None': +) -> RenderData | None: """ Takes the widgets, layout, structure and a dict of variables meant for the template engine and injects the variables required by the widgets, if the widgets are indeed in use. diff --git a/src/onegov/directory/__init__.py b/src/onegov/directory/__init__.py index 915262f4e7..9234b528b9 100644 --- a/src/onegov/directory/__init__.py +++ b/src/onegov/directory/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.directory.archive import DirectoryArchive, DirectoryZipArchive from onegov.directory.models import Directory, DirectoryEntry from onegov.directory.collections import DirectoryCollection diff --git a/src/onegov/directory/archive.py b/src/onegov/directory/archive.py index e82b888f24..8fbe10339e 100644 --- a/src/onegov/directory/archive.py +++ b/src/onegov/directory/archive.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import mimetypes import shutil import os @@ -67,7 +69,7 @@ def __init__(self, directory: Directory, archive_path: Path) -> None: self.fields_by_id = {f.id: f for f in directory.fields} self.archive_path = archive_path - def get_field(self, key: str) -> 'ParsedField | None': + def get_field(self, key: str) -> ParsedField | None: """ CSV Files header parsing is inconsistent with the the internal id ( field.id) of the field. The headers are lovercased, so that the first @@ -84,7 +86,7 @@ def parse_fileinput( self, key: str, value: str, - field: 'FileinputField' + field: FileinputField ) -> Bunch | None: # FIXME: Use NamedTuple if not value: @@ -112,13 +114,13 @@ def parse_multiplefileinput( self, key: str, value: str, - field: 'MultipleFileinputField' + field: MultipleFileinputField ) -> tuple[Bunch, ...]: # FIXME: Use NamedTuple if not value: return () - def iter_files() -> 'Iterator[Bunch]': + def iter_files() -> Iterator[Bunch]: for val in value.split(os.pathsep): # be extra paranoid about these path values -> they could # potentially be used to access files on the local system @@ -144,7 +146,7 @@ def parse_generic( self, key: str, value: str, - field: 'ParsedField' + field: ParsedField ) -> object: return field.parse(value) @@ -152,7 +154,7 @@ def parse_item( self, key: str, value: str - ) -> 'tuple[str, Any | None] | UnknownFieldType': + ) -> tuple[str, Any | None] | UnknownFieldType: field = self.get_field(key) @@ -170,7 +172,7 @@ def parse_item( def parse( self, - record: 'SupportsItems[str, str]' + record: SupportsItems[str, str] ) -> dict[str, Any | None]: return dict( @@ -191,7 +193,7 @@ def read( skip_existing: bool = True, limit: int = 0, apply_metadata: bool = True, - after_import: 'Callable[[DirectoryEntry], Any] | None' = None + after_import: Callable[[DirectoryEntry], Any] | None = None ) -> Directory: """ Reads the archive resulting in a dictionary and entries. @@ -309,7 +311,7 @@ def read_metadata(self) -> dict[str, Any]: except FileNotFoundError as exception: raise MissingFileError('metadata.json') from exception - def read_data(self) -> 'Sequence[dict[str, Any]]': + def read_data(self) -> Sequence[dict[str, Any]]: """ Returns the entries as a sequence of dictionaries. """ if (self.path / 'data.json').exists(): @@ -344,14 +346,14 @@ class DirectoryArchiveWriter: path: Path format: Literal['json', 'csv', 'xlsx'] - transform: 'FieldValueTransform' + transform: FieldValueTransform def write( self, directory: Directory, *args: Any, - entry_filter: 'DirectoryEntryFilter | None' = None, - query: 'Query[DirectoryEntry] | None' = None, + entry_filter: DirectoryEntryFilter | None = None, + query: Query[DirectoryEntry] | None = None, **kwargs: Any ) -> None: """ Writes the given directory. """ @@ -378,8 +380,8 @@ def write_directory_metadata(self, directory: Directory) -> None: def write_directory_entries( self, directory: Directory, - entry_filter: 'DirectoryEntryFilter | None' = None, - query: 'Query[DirectoryEntry] | None' = None + entry_filter: DirectoryEntryFilter | None = None, + query: Query[DirectoryEntry] | None = None ) -> None: """ Writes the directory entries. Allows filtering with custom entry_filter function as well as passing a query object """ @@ -390,7 +392,7 @@ def write_directory_entries( def file_path( entry: DirectoryEntry, - field: 'ParsedField', + field: ParsedField, value: dict[str, Any], suffix: str = '' ) -> str: @@ -403,7 +405,7 @@ def file_path( def as_tuples( entry: DirectoryEntry - ) -> 'Iterator[tuple[str, Any | None]]': + ) -> Iterator[tuple[str, Any | None]]: for field in fields: value = entry.values.get(field.id) @@ -461,7 +463,7 @@ def as_dict(entry: DirectoryEntry) -> dict[str, Any | None]: def write_paths( self, - session: 'Session', + session: Session, paths: dict[str, str], fid_to_entry: dict[str, str] | None = None ) -> None: @@ -525,15 +527,15 @@ def write_paths( for tempfile in tempfiles: tempfile.close() - def write_json(self, path: Path, data: 'JSON_ro') -> None: + def write_json(self, path: Path, data: JSON_ro) -> None: with open(str(path), 'w') as f: json.dump(data, f, sort_keys=True, indent=2) - def write_xlsx(self, path: Path, data: 'Iterable[dict[str, Any]]') -> None: + def write_xlsx(self, path: Path, data: Iterable[dict[str, Any]]) -> None: with open(str(path), 'wb') as f: f.write(convert_list_of_dicts_to_xlsx(data)) - def write_csv(self, path: Path, data: 'Iterable[dict[str, Any]]') -> None: + def write_csv(self, path: Path, data: Iterable[dict[str, Any]]) -> None: with open(str(path), 'w') as f: f.write(convert_list_of_dicts_to_csv(data)) @@ -562,9 +564,9 @@ class DirectoryArchive(DirectoryArchiveReader, DirectoryArchiveWriter): def __init__( self, - path: 'StrPath', + path: StrPath, format: Literal['json', 'csv', 'xlsx'] = 'json', - transform: 'FieldValueTransform | None ' = None + transform: FieldValueTransform | None = None ): """ Initialise the archive at the given path (must exist). @@ -600,7 +602,7 @@ class DirectoryZipArchive: def __init__( self, - path: 'StrPath', + path: StrPath, *args: Any, **kwargs: Any ): @@ -609,7 +611,7 @@ def __init__( self.archive = DirectoryArchive(self.temp.name, *args, **kwargs) @classmethod - def from_buffer(cls, buffer: 'SupportsReadAndSeek') -> 'Self': + def from_buffer(cls, buffer: SupportsReadAndSeek) -> Self: """ Creates a zip archive instance from a file object in memory. """ f = NamedTemporaryFile() # noqa: SIM115 diff --git a/src/onegov/directory/collections/__init__.py b/src/onegov/directory/collections/__init__.py index 0ad30990b1..c640c3670e 100644 --- a/src/onegov/directory/collections/__init__.py +++ b/src/onegov/directory/collections/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.directory.collections.directory import DirectoryCollection from onegov.directory.collections.directory_entry import ( DirectoryEntryCollection) diff --git a/src/onegov/directory/collections/directory.py b/src/onegov/directory/collections/directory.py index 03e2072053..9f3653d30c 100644 --- a/src/onegov/directory/collections/directory.py +++ b/src/onegov/directory/collections/directory.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.collection import GenericCollection from onegov.core.utils import normalize_for_url, increment_name, is_uuid from onegov.directory.models import Directory @@ -18,15 +20,15 @@ class DirectoryCollection(GenericCollection[DirectoryT]): @overload def __init__( - self: 'DirectoryCollection[Directory]', - session: 'Session', + self: DirectoryCollection[Directory], + session: Session, type: Literal['*', 'generic'] = '*' ) -> None: ... @overload - def __init__(self, session: 'Session', type: str) -> None: ... + def __init__(self, session: Session, type: str) -> None: ... - def __init__(self, session: 'Session', type: str = '*') -> None: + def __init__(self, session: Session, type: str = '*') -> None: super().__init__(session) self.type = type @@ -37,7 +39,7 @@ def model_class(self) -> type[DirectoryT]: Directory # type:ignore[arg-type] ) - def query(self) -> 'Query[DirectoryT]': + def query(self) -> Query[DirectoryT]: return super().query().order_by(self.model_class.order) def add(self, **kwargs: Any) -> DirectoryT: @@ -76,13 +78,13 @@ def by_name(self, name: str) -> DirectoryT | None: class EntryRecipientCollection: - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session - def query(self) -> 'Query[EntryRecipient]': + def query(self) -> Query[EntryRecipient]: return self.session.query(EntryRecipient) - def by_id(self, id: 'str | UUID') -> EntryRecipient | None: + def by_id(self, id: str | UUID) -> EntryRecipient | None: if is_uuid(id): return self.query().filter(EntryRecipient.id == id).first() return None @@ -90,7 +92,7 @@ def by_id(self, id: 'str | UUID') -> EntryRecipient | None: def add( self, address: str, - directory_id: 'UUID', + directory_id: UUID, confirmed: bool = False ) -> EntryRecipient: diff --git a/src/onegov/directory/collections/directory_entry.py b/src/onegov/directory/collections/directory_entry.py index d8734c9b4b..3bb7662da6 100644 --- a/src/onegov/directory/collections/directory_entry.py +++ b/src/onegov/directory/collections/directory_entry.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from itertools import groupby from onegov.core.collection import GenericCollection, Pagination from onegov.core.utils import toggle @@ -26,14 +28,14 @@ class DirectorySearchWidget(Protocol[DirectoryEntryT]): @property def name(self) -> str: ... @property - def search_query(self) -> 'Query[DirectoryEntryT]': ... + def search_query(self) -> Query[DirectoryEntryT]: ... def adapt( self, - query: 'Query[DirectoryEntryT]' - ) -> 'Query[DirectoryEntryT]': ... + query: Query[DirectoryEntryT] + ) -> Query[DirectoryEntryT]: ... - def html(self, layout: Any) -> 'Markup': ... + def html(self, layout: Any) -> Markup: ... class DirectoryEntryCollection( @@ -50,11 +52,11 @@ class DirectoryEntryCollection( def __init__( self, - directory: 'Directory', + directory: Directory, type: str = '*', - keywords: 'Mapping[str, list[str]] | None' = None, + keywords: Mapping[str, list[str]] | None = None, page: int = 0, - search_widget: 'DirectorySearchWidget[DirectoryEntryT] | None' = None + search_widget: DirectorySearchWidget[DirectoryEntryT] | None = None ) -> None: super().__init__(object_session(directory)) @@ -71,7 +73,7 @@ def __eq__(self, other: object) -> bool: and self.page == other.page ) - def subset(self) -> 'Query[DirectoryEntryT]': + def subset(self) -> Query[DirectoryEntryT]: return self.query() @property @@ -82,7 +84,7 @@ def search(self) -> str | None: return self.search_widget.name @property - def search_query(self) -> 'Query[DirectoryEntryT] | None': + def search_query(self) -> Query[DirectoryEntryT] | None: if self.search_widget is None: return None @@ -92,7 +94,7 @@ def search_query(self) -> 'Query[DirectoryEntryT] | None': def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__( self.directory, self.type, @@ -103,7 +105,7 @@ def page_by_index(self, index: int) -> 'Self': def by_name(self, name: str) -> DirectoryEntryT | None: return self.query().filter_by(name=name).first() - def query(self) -> 'Query[DirectoryEntryT]': + def query(self) -> Query[DirectoryEntryT]: cls = self.model_class query = super().query().filter_by(directory_id=self.directory.id) @@ -138,7 +140,7 @@ def keyword_group(value: str) -> str: def valid_keywords( self, - parameters: 'Mapping[str, T]' + parameters: Mapping[str, T] ) -> dict[str, T]: valid_keywords = { @@ -165,8 +167,8 @@ def model_class(self) -> type[DirectoryEntryT]: def available_filters( self, sort_choices: bool = False, - sortfunc: 'Callable[[str], SupportsRichComparison] | None ' = None - ) -> 'Iterable[tuple[str, str, list[str]]]': + sortfunc: Callable[[str], SupportsRichComparison] | None = None + ) -> Iterable[tuple[str, str, list[str]]]: """ Retrieve the filters with their choices. By default the choices are returned in the same order as defined in the @@ -186,7 +188,7 @@ def available_filters( ) } - def maybe_sorted(values: 'Iterable[str]') -> list[str]: + def maybe_sorted(values: Iterable[str]) -> list[str]: if not sort_choices: return list(values) return sorted(values, key=sortfunc) @@ -200,7 +202,7 @@ def for_keywords( self, singular: bool = False, **keywords: list[str] - ) -> 'Self': + ) -> Self: if not self.directory.configuration.keywords: return self @@ -217,7 +219,7 @@ def for_toggled_keyword_value( keyword: str, value: str, singular: bool = False, - ) -> 'Self': + ) -> Self: if not self.directory.configuration.keywords: return self @@ -243,7 +245,7 @@ def for_toggled_keyword_value( keywords=parameters ) - def without_keywords(self) -> 'Self': + def without_keywords(self) -> Self: return self.__class__( directory=self.directory, type=self.type, diff --git a/src/onegov/directory/errors.py b/src/onegov/directory/errors.py index 5bc40e1447..3537378c98 100644 --- a/src/onegov/directory/errors.py +++ b/src/onegov/directory/errors.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import TYPE_CHECKING if TYPE_CHECKING: from onegov.directory.models import DirectoryEntry @@ -11,8 +13,8 @@ class OnegovDirectoryError(Exception): class ValidationError(OnegovDirectoryError): def __init__( self, - entry: 'DirectoryEntry', - errors: '_FormErrors', + entry: DirectoryEntry, + errors: _FormErrors, *args: object ) -> None: diff --git a/src/onegov/directory/migration.py b/src/onegov/directory/migration.py index 0d0e8f8bce..b36c777559 100644 --- a/src/onegov/directory/migration.py +++ b/src/onegov/directory/migration.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.directory.models.directory_entry import DirectoryEntry from onegov.form import as_internal_id from onegov.form import flatten_fieldsets @@ -25,9 +27,9 @@ class DirectoryMigration: def __init__( self, - directory: 'Directory', + directory: Directory, new_structure: str | None = None, - new_configuration: 'DirectoryConfiguration | None' = None, + new_configuration: DirectoryConfiguration | None = None, old_structure: str | None = None ): @@ -84,7 +86,7 @@ def possible(self) -> bool: return False @property - def entries(self) -> 'Iterable[DirectoryEntry]': + def entries(self) -> Iterable[DirectoryEntry]: session = object_session(self.directory) if not session: @@ -179,7 +181,7 @@ def get_converter( self, old_type: str, new_type: str - ) -> 'Callable[[Any], Any] | None': + ) -> Callable[[Any], Any] | None: if old_type == 'password': return None # disabled to avoid accidental leaks @@ -211,13 +213,13 @@ def textarea_to_code(self, value: str) -> str: def text_to_code(self, value: str) -> str: return value - def date_to_text(self, value: 'date') -> str: + def date_to_text(self, value: date) -> str: return '{:%d.%m.%Y}'.format(value) - def datetime_to_text(self, value: 'datetime') -> str: + def datetime_to_text(self, value: datetime) -> str: return '{:%d.%m.%Y %H:%M}'.format(value) - def time_to_text(self, value: 'time') -> str: + def time_to_text(self, value: time) -> str: return '{:%H:%M}'.format(value) def radio_to_checkbox(self, value: str) -> list[str]: diff --git a/src/onegov/directory/models/__init__.py b/src/onegov/directory/models/__init__.py index 11924a0129..79e9d86150 100644 --- a/src/onegov/directory/models/__init__.py +++ b/src/onegov/directory/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.directory.models.directory import Directory from onegov.directory.models.directory_entry import DirectoryEntry diff --git a/src/onegov/directory/models/directory.py b/src/onegov/directory/models/directory.py index c3f7029ea7..964cc9d3b4 100644 --- a/src/onegov/directory/models/directory.py +++ b/src/onegov/directory/models/directory.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import inspect from email_validator import validate_email @@ -84,7 +86,7 @@ class DirectoryFile(File): linked_directory_entries: relationship[list[DirectoryEntry]] @property - def directory_entry(self) -> 'DirectoryEntry | None': + def directory_entry(self) -> DirectoryEntry | None: # we gracefully handle if there are no linked entries, even though # there should always be exactly one entries = self.linked_directory_entries @@ -115,43 +117,43 @@ def es_public(self) -> bool: return False # to be overridden downstream #: An interal id for references (not public) - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The public, unique name of the directory - name: 'Column[str]' = Column(Text, nullable=False, unique=True) + name: Column[str] = Column(Text, nullable=False, unique=True) #: The title of the directory - title: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) #: Describes the directory briefly - lead: 'Column[str | None]' = Column(Text, nullable=True) + lead: Column[str | None] = Column(Text, nullable=True) #: The normalized title for sorting - order: 'Column[str]' = Column(Text, nullable=False, index=True) + order: Column[str] = Column(Text, nullable=False, index=True) #: The polymorphic type of the directory - type: 'Column[str]' = Column( + type: Column[str] = Column( Text, nullable=False, default=lambda: 'generic' ) #: The data structure of the contained entries - structure: 'Column[str]' = Column(Text, nullable=False) + structure: Column[str] = Column(Text, nullable=False) #: The configuration of the contained entries - configuration: 'Column[DirectoryConfiguration]' = Column( + configuration: Column[DirectoryConfiguration] = Column( DirectoryConfigurationStorage, nullable=False ) #: The number of entries in the directory @aggregated('entries', Column(Integer, nullable=False, default=0)) - def count(self) -> 'ColumnElement[int]': + def count(self) -> ColumnElement[int]: return func.count('1') __mapper_args__ = { @@ -159,7 +161,7 @@ def count(self) -> 'ColumnElement[int]': 'polymorphic_identity': 'generic' } - entries: 'relationship[list[DirectoryEntry]]' = relationship( + entries: relationship[list[DirectoryEntry]] = relationship( 'DirectoryEntry', order_by='DirectoryEntry.order', back_populates='directory' @@ -170,7 +172,7 @@ def entry_cls_name(self) -> str: return 'DirectoryEntry' @property - def entry_cls(self) -> '_type[DirectoryEntry]': + def entry_cls(self) -> _type[DirectoryEntry]: return self.__class__._decl_class_registry[ # type:ignore self.entry_cls_name ] @@ -178,8 +180,8 @@ def entry_cls(self) -> '_type[DirectoryEntry]': def add( self, values: dict[str, Any], - type: 'str | InheritType' = INHERIT - ) -> 'DirectoryEntry': + type: str | InheritType = INHERIT + ) -> DirectoryEntry: start = values.pop('publication_start', None) end = values.pop('publication_end', None) @@ -203,9 +205,9 @@ def add( def add_by_form( self, - form: 'DirectoryEntryForm', - type: 'str | InheritType' = INHERIT - ) -> 'DirectoryEntry': + form: DirectoryEntryForm, + type: str | InheritType = INHERIT + ) -> DirectoryEntry: entry = self.add(form.mixed_data, type) @@ -217,11 +219,11 @@ def add_by_form( def update( self, - entry: 'DirectoryEntry', - values: 'Mapping[str, Any]', + entry: DirectoryEntry, + values: Mapping[str, Any], set_name: bool = False, force_update: bool = False - ) -> 'DirectoryEntry': + ) -> DirectoryEntry: session = object_session(self) @@ -464,7 +466,7 @@ def title_observer(self, title: str) -> None: def structure_configuration_observer( self, structure: str, - configuration: 'DirectoryConfiguration' + configuration: DirectoryConfiguration ) -> None: self.migration(structure, configuration).execute() @@ -477,7 +479,7 @@ def entry_with_name_exists(self, name: str) -> bool: def migration( self, new_structure: str, - new_configuration: 'DirectoryConfiguration' + new_configuration: DirectoryConfiguration ) -> DirectoryMigration: return DirectoryMigration( @@ -487,49 +489,49 @@ def migration( ) @property - def fields(self) -> 'Sequence[ParsedField]': + def fields(self) -> Sequence[ParsedField]: return self.fields_from_structure(self.structure) @staticmethod @lru_cache(maxsize=1) - def fields_from_structure(structure: str) -> 'Sequence[ParsedField]': + def fields_from_structure(structure: str) -> Sequence[ParsedField]: return tuple(flatten_fieldsets(parse_formcode(structure))) @property - def basic_fields(self) -> 'Sequence[BasicParsedField]': + def basic_fields(self) -> Sequence[BasicParsedField]: return tuple( f for f in self.fields if f.type != 'fileinput' and f.type != 'multiplefileinput' ) @property - def file_fields(self) -> 'Sequence[FileParsedField]': + def file_fields(self) -> Sequence[FileParsedField]: return tuple( f for f in self.fields if f.type == 'fileinput' or f.type == 'multiplefileinput' ) - def field_by_id(self, id: str) -> 'ParsedField | None': + def field_by_id(self, id: str) -> ParsedField | None: query = (f for f in self.fields if f.human_id == id or f.id == id) return next(query, None) @property - def form_obj(self) -> 'DirectoryEntryForm': + def form_obj(self) -> DirectoryEntryForm: return self.form_obj_from_structure(self.structure) @property - def form_class(self) -> '_type[DirectoryEntryForm]': + def form_class(self) -> _type[DirectoryEntryForm]: return self.form_class_from_structure(self.structure) @instance_lru_cache(maxsize=1) - def form_obj_from_structure(self, structure: str) -> 'DirectoryEntryForm': + def form_obj_from_structure(self, structure: str) -> DirectoryEntryForm: return self.form_class_from_structure(structure)() @instance_lru_cache(maxsize=1) def form_class_from_structure( self, structure: str - ) -> '_type[DirectoryEntryForm]': + ) -> _type[DirectoryEntryForm]: directory = self @@ -552,7 +554,7 @@ def mixed_data(self) -> dict[str, Any]: def populate_obj( self, - obj: 'DirectoryEntry', + obj: DirectoryEntry, directory_update: bool = True ) -> None: @@ -569,7 +571,7 @@ def populate_obj( if directory_update: directory.update(obj, self.mixed_data) - def process_obj(self, obj: 'DirectoryEntry') -> None: + def process_obj(self, obj: DirectoryEntry) -> None: super().process_obj(obj) for field in directory.fields: @@ -595,14 +597,14 @@ class EntryRecipient(Base, TimestampMixin): __tablename__ = 'entry_recipients' #: the id of the recipient, used in the url - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the email address of the recipient - address: 'Column[str]' = Column(Text, nullable=False) + address: Column[str] = Column(Text, nullable=False) @validates('address') def validate_address(self, key: str, address: str) -> str: @@ -610,18 +612,18 @@ def validate_address(self, key: str, address: str) -> str: return address #: this token is used for confirm and unsubscribe - token: 'Column[str]' = Column(Text, nullable=False, default=random_token) + token: Column[str] = Column(Text, nullable=False, default=random_token) #: when recipients are added, they are unconfirmed. At this point they get #: one e-mail with a confirmation link. If they ignore said e-mail they #: should not get another one. - confirmed: 'Column[bool]' = Column(Boolean, nullable=False, default=False) + confirmed: Column[bool] = Column(Boolean, nullable=False, default=False) @property - def subscription(self) -> 'EntrySubscription': + def subscription(self) -> EntrySubscription: return EntrySubscription(self, self.token) - directory_id: 'Column[uuid.UUID]' = Column( + directory_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] nullable=False ) @@ -635,7 +637,7 @@ def __init__(self, recipient: EntryRecipient, token: str): self.token = token @property - def recipient_id(self) -> 'uuid.UUID': + def recipient_id(self) -> uuid.UUID: # even though this seems redundant, we need this property # for morepath, so it can match it to the path variable return self.recipient.id diff --git a/src/onegov/directory/models/directory_entry.py b/src/onegov/directory/models/directory_entry.py index acb6ecdc7a..b6b33ff257 100644 --- a/src/onegov/directory/models/directory_entry.py +++ b/src/onegov/directory/models/directory_entry.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import ContentMixin from onegov.core.orm.mixins import TimestampMixin @@ -46,38 +48,38 @@ def es_public(self) -> bool: return False # to be overridden downstream #: An interal id for references (not public) - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The public id of the directory entry - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: The directory this entry belongs to - directory_id: 'Column[UUID]' = Column( + directory_id: Column[UUID] = Column( ForeignKey('directories.id'), nullable=False) #: the polymorphic type of the entry - type: 'Column[str]' = Column( + type: Column[str] = Column( Text, nullable=False, default=lambda: 'generic' ) #: The order of the entry in the directory - order: 'Column[str]' = Column(Text, nullable=False, index=True) + order: Column[str] = Column(Text, nullable=False, index=True) #: The title of the entry - title: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) #: Describes the entry briefly - lead: 'Column[str | None]' = Column(Text, nullable=True) + lead: Column[str | None] = Column(Text, nullable=True) #: All keywords defined for this entry (indexed) - _keywords: 'Column[dict[str, str] | None]' = Column( # type:ignore - MutableDict.as_mutable(HSTORE), + _keywords: Column[dict[str, str] | None] = Column( # type:ignore + MutableDict.as_mutable(HSTORE), # type:ignore[no-untyped-call] nullable=True, name='keywords' ) @@ -92,7 +94,7 @@ def es_public(self) -> bool: Index('unique_entry_name', 'directory_id', 'name', unique=True), ) - directory: 'relationship[Directory]' = relationship( + directory: relationship[Directory] = relationship( 'Directory', back_populates='entries' ) @@ -120,7 +122,7 @@ def keywords(self) -> set[str]: # FIXME: asymmetric properties are not supported by mypy, switch to # a custom descriptor, if desired. @keywords.setter - def keywords(self, value: 'Collection[str] | None') -> None: + def keywords(self, value: Collection[str] | None) -> None: self._keywords = dict.fromkeys(value, '') if value else None @property diff --git a/src/onegov/directory/types/__init__.py b/src/onegov/directory/types/__init__.py index e75b5218ee..03b348ea5b 100644 --- a/src/onegov/directory/types/__init__.py +++ b/src/onegov/directory/types/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.directory.types.directory_configuration import ( DirectoryConfiguration, DirectoryConfigurationStorage diff --git a/src/onegov/directory/types/directory_configuration.py b/src/onegov/directory/types/directory_configuration.py index 54ea5f7a62..e633ecc598 100644 --- a/src/onegov/directory/types/directory_configuration.py +++ b/src/onegov/directory/types/directory_configuration.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re import yaml @@ -15,7 +17,7 @@ from typing import overload, Any, Literal, NoReturn, TYPE_CHECKING if TYPE_CHECKING: - from collections.abc import Mapping + from collections.abc import Callable, Mapping from sqlalchemy.engine import Dialect from typing import Self, TypeVar @@ -25,7 +27,7 @@ _Base = TypeDecorator # XXX i18n -SAFE_FORMAT_TRANSLATORS = { +SAFE_FORMAT_TRANSLATORS: dict[type[object], Callable[[Any], str]] = { date: lambda d: d.strftime('%d.%m.%Y'), datetime: lambda d: d.strftime('%d.%m.%Y %H:%M'), time: lambda t: t.strftime('%H:%M') @@ -56,13 +58,13 @@ class DirectoryConfigurationStorage(_Base, ScalarCoercible): impl = TEXT @property - def python_type(self) -> type['DirectoryConfiguration']: + def python_type(self) -> type[DirectoryConfiguration]: return DirectoryConfiguration def process_bind_param( self, - value: 'DirectoryConfiguration | None', - dialect: 'Dialect' + value: DirectoryConfiguration | None, + dialect: Dialect ) -> str | None: if value is None: @@ -73,8 +75,8 @@ def process_bind_param( def process_result_value( self, value: str | None, - dialect: 'Dialect' - ) -> 'DirectoryConfiguration | None': + dialect: Dialect + ) -> DirectoryConfiguration | None: if value is None: return None @@ -100,11 +102,11 @@ def to_yaml(self) -> str: return text.replace('\n- ', '\n - ') @classmethod - def from_json(cls, text: str) -> 'Self': + def from_json(cls, text: str) -> Self: return cls(**json.loads(text)) @classmethod - def from_yaml(cls, text: str) -> 'Self': + def from_yaml(cls, text: str) -> Self: return cls(**yaml.safe_load(text)) @@ -166,7 +168,7 @@ def __init__( self.show_as_thumbnails = show_as_thumbnails def __setattr__(self, name: str, value: object) -> None: - self.changed() + self.changed() # type:ignore[no-untyped-call] return super().__setattr__(name, value) def missing_fields(self, formcode: str | None) -> dict[str, list[str]]: @@ -209,8 +211,8 @@ def missing_fields(self, formcode: str | None) -> dict[str, list[str]]: @overload @classmethod def coerce( # type:ignore[overload-overlap] - cls, key: str, value: '_MutableT' - ) -> '_MutableT': ... + cls, key: str, value: _MutableT + ) -> _MutableT: ... @overload @classmethod def coerce(cls, key: str, value: object) -> NoReturn: ... @@ -224,7 +226,7 @@ def coerce(cls, key: str, value: object) -> object: def join( self, - data: 'Mapping[str, Any]', + data: Mapping[str, Any], attribute: str, separator: str = '\n' ) -> str: @@ -242,11 +244,11 @@ def render(value: object) -> str: data.get(as_internal_id(key)) for key in getattr(self, attribute) )) - def safe_format(self, fmt: str, data: 'Mapping[str, Any]') -> str: + def safe_format(self, fmt: str, data: Mapping[str, Any]) -> str: return safe_format( fmt, self.for_safe_format(data), adapt=as_internal_id) - def for_safe_format(self, data: 'Mapping[str, Any]') -> dict[str, Any]: + def for_safe_format(self, data: Mapping[str, Any]) -> dict[str, Any]: return { k: SAFE_FORMAT_TRANSLATORS.get(type(v), str)(v) for k, v in data.items() @@ -256,21 +258,21 @@ def for_safe_format(self, data: 'Mapping[str, Any]') -> dict[str, Any]: ) } - def extract_name(self, data: 'Mapping[str, Any]') -> str: + def extract_name(self, data: Mapping[str, Any]) -> str: return normalize_for_url(self.extract_title(data)) - def extract_title(self, data: 'Mapping[str, Any]') -> str: + def extract_title(self, data: Mapping[str, Any]) -> str: return self.safe_format(self.title, data) - def extract_lead(self, data: 'Mapping[str, Any]') -> str | None: + def extract_lead(self, data: Mapping[str, Any]) -> str | None: return self.lead and self.safe_format(self.lead, data) - def extract_link(self, data: 'Mapping[str, Any]') -> str | None: + def extract_link(self, data: Mapping[str, Any]) -> str | None: return self.link_pattern and self.safe_format(self.link_pattern, { k: quote_plus(v) for k, v in self.for_safe_format(data).items() }) - def extract_order(self, data: 'Mapping[str, Any]') -> str: + def extract_order(self, data: Mapping[str, Any]) -> str: # by default we use the title as order attribute = ( (self.order and 'order') @@ -281,7 +283,7 @@ def extract_order(self, data: 'Mapping[str, Any]') -> str: return order - def extract_searchable(self, data: 'Mapping[str, Any]') -> str: + def extract_searchable(self, data: Mapping[str, Any]) -> str: # Remove non-searchable fields from data assert self.searchable is not None data = {as_internal_id(id): data.get(as_internal_id(id)) @@ -289,7 +291,7 @@ def extract_searchable(self, data: 'Mapping[str, Any]') -> str: return self.join(data, 'searchable') - def extract_keywords(self, data: 'Mapping[str, Any]') -> set[str] | None: + def extract_keywords(self, data: Mapping[str, Any]) -> set[str] | None: if not self.keywords: return None @@ -308,4 +310,4 @@ def extract_keywords(self, data: 'Mapping[str, Any]') -> set[str] | None: return keywords -DirectoryConfiguration.associate_with(DirectoryConfigurationStorage) +DirectoryConfiguration.associate_with(DirectoryConfigurationStorage) # type:ignore[no-untyped-call] diff --git a/src/onegov/directory/upgrade.py b/src/onegov/directory/upgrade.py index a28a3606a1..5d7eca28fc 100644 --- a/src/onegov/directory/upgrade.py +++ b/src/onegov/directory/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + from onegov.core.orm.types import UTCDateTime from onegov.core.upgrade import upgrade_task, UpgradeContext from onegov.directory import Directory diff --git a/src/onegov/election_day/__init__.py b/src/onegov/election_day/__init__.py index a8422940e4..bfc311f114 100644 --- a/src/onegov/election_day/__init__.py +++ b/src/onegov/election_day/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.election_day') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/election_day/app.py b/src/onegov/election_day/app.py index 45d7e758cd..bff8425894 100644 --- a/src/onegov/election_day/app.py +++ b/src/onegov/election_day/app.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re from dectate import directive @@ -57,14 +59,14 @@ class ElectionDayApp(Framework, FormApp, UserApp, DepotApp): screen_widget = directive(ScreenWidgetAction) @property - def principal(self) -> 'Canton | Municipality': + def principal(self) -> Canton | Municipality: """ Returns the principal of the election day app. See :class:`onegov.election_day.models.principal.Principal`. """ return self.cache.get_or_create('principal', self.load_principal) - def load_principal(self) -> 'Canton | Municipality | None': + def load_principal(self) -> Canton | Municipality | None: """ The principal is defined in the ``principal.yml`` file stored on the applications filestorage root. @@ -113,7 +115,7 @@ def theme_options(self) -> dict[str, Any]: return {'primary-color': color} @property - def pages_cache(self) -> 'RedisCacheRegion': + def pages_cache(self) -> RedisCacheRegion: """ A cache for pages. """ expiration_time = 300 if self.principal and hasattr(self.principal, 'cache_expiration_time'): @@ -156,7 +158,7 @@ def get_i18n_default_locale() -> str: @ElectionDayApp.setting(section='content_security_policy', name='default') -def org_content_security_policy() -> 'ContentSecurityPolicy': +def org_content_security_policy() -> ContentSecurityPolicy: policy = default_content_security_policy() policy.script_src.remove(UNSAFE_EVAL) policy.script_src.remove(UNSAFE_INLINE) @@ -166,8 +168,8 @@ def org_content_security_policy() -> 'ContentSecurityPolicy': @ElectionDayApp.tween_factory(under=content_security_policy_tween_factory) def enable_iframes_and_analytics_tween_factory( app: ElectionDayApp, - handler: 'Callable[[ElectionDayRequest], Response]' -) -> 'Callable[[ElectionDayRequest], Response]': + handler: Callable[[ElectionDayRequest], Response] +) -> Callable[[ElectionDayRequest], Response]: no_iframe_paths = ( r'/auth/.*', @@ -187,7 +189,7 @@ def enable_iframes_and_analytics_tween_factory( def enable_iframes_and_analytics_tween( request: ElectionDayRequest - ) -> 'Response': + ) -> Response: """ Enables iframes and analytics. """ result = handler(request) @@ -213,9 +215,9 @@ def enable_iframes_and_analytics_tween( @ElectionDayApp.tween_factory(over=current_language_tween_factory) def override_language_tween_factory( app: ElectionDayApp, - handler: 'Callable[[ElectionDayRequest], Response]' -) -> 'Callable[[ElectionDayRequest], Response]': - def override_language_tween(request: ElectionDayRequest) -> 'Response': + handler: Callable[[ElectionDayRequest], Response] +) -> Callable[[ElectionDayRequest], Response]: + def override_language_tween(request: ElectionDayRequest) -> Response: """ Allows the current language to be overwritten using a query parameter. @@ -236,10 +238,10 @@ def override_language_tween(request: ElectionDayRequest) -> 'Response': ) def cache_control_tween_factory( app: ElectionDayApp, - handler: 'Callable[[ElectionDayRequest], Response]' -) -> 'Callable[[ElectionDayRequest], Response]': + handler: Callable[[ElectionDayRequest], Response] +) -> Callable[[ElectionDayRequest], Response]: - def cache_control_tween(request: ElectionDayRequest) -> 'Response': + def cache_control_tween(request: ElectionDayRequest) -> Response: """ Set headers and cookies for cache control. Makes sure, pages are not cached downstream when logged in by setting @@ -270,8 +272,8 @@ def cache_control_tween(request: ElectionDayRequest) -> 'Response': ) def micro_cache_anonymous_pages_tween_factory( app: ElectionDayApp, - handler: 'Callable[[ElectionDayRequest], Response]' -) -> 'Callable[[ElectionDayRequest], Response]': + handler: Callable[[ElectionDayRequest], Response] +) -> Callable[[ElectionDayRequest], Response]: cache_paths = ( '/ballot/.*', @@ -286,7 +288,7 @@ def micro_cache_anonymous_pages_tween_factory( ) cache_paths_re = re.compile(r'^({})$'.format('|'.join(cache_paths))) - def should_cache_fn(response: 'Response') -> bool: + def should_cache_fn(response: Response) -> bool: return ( response.status_code == 200 and 'Set-Cookie' not in response.headers @@ -294,7 +296,7 @@ def should_cache_fn(response: 'Response') -> bool: def micro_cache_anonymous_pages_tween( request: ElectionDayRequest - ) -> 'Response': + ) -> Response: """ Cache all pages for 5 minutes. """ # do not cache POST, DELETE etc. @@ -354,7 +356,7 @@ def get_webasset_output() -> str: @ElectionDayApp.webasset('common') -def get_common_asset() -> 'Iterator[str]': +def get_common_asset() -> Iterator[str]: # Common assets unlikely to change yield 'modernizr.js' @@ -382,7 +384,7 @@ def get_common_asset() -> 'Iterator[str]': @ElectionDayApp.webasset('custom') -def get_custom_asset() -> 'Iterator[str]': +def get_custom_asset() -> Iterator[str]: # common code yield 'common.js' yield 'form_dependencies.js' @@ -406,7 +408,7 @@ def get_custom_asset() -> 'Iterator[str]': @ElectionDayApp.webasset('backend_common') -def get_backend_common_asset() -> 'Iterator[str]': +def get_backend_common_asset() -> Iterator[str]: # Common assets unlikely to change, only used in the backend yield 'jquery.datetimepicker.css' yield 'jquery.datetimepicker.js' @@ -415,6 +417,6 @@ def get_backend_common_asset() -> 'Iterator[str]': @ElectionDayApp.webasset('screen') -def get_screen_asset() -> 'Iterator[str]': +def get_screen_asset() -> Iterator[str]: # Code used for screen update yield 'screen.js' diff --git a/src/onegov/election_day/cli.py b/src/onegov/election_day/cli.py index 8f514815e7..e37d414ba5 100644 --- a/src/onegov/election_day/cli.py +++ b/src/onegov/election_day/cli.py @@ -1,4 +1,6 @@ """ Provides commands used to initialize election day websites. """ +from __future__ import annotations + import click import os @@ -32,7 +34,7 @@ @cli.command(context_settings={'creates_path': True}) @pass_group_context -def add(group_context: 'GroupContext') -> 'Processor': +def add(group_context: GroupContext) -> Processor: """ Adds an election day instance with to the database. For example: .. code-block:: bash @@ -42,8 +44,8 @@ def add(group_context: 'GroupContext') -> 'Processor': """ def add_instance( - request: 'ElectionDayRequest', - app: 'ElectionDayApp' + request: ElectionDayRequest, + app: ElectionDayApp ) -> None: app.cache.flush() if not app.principal: @@ -56,7 +58,7 @@ def add_instance( @cli.command() @pass_group_context -def fetch(group_context: 'GroupContext') -> 'Processor': +def fetch(group_context: GroupContext) -> Processor: """ Fetches the results from other instances as defined in the principal.yml. Only fetches results from the same namespace. @@ -67,8 +69,8 @@ def fetch(group_context: 'GroupContext') -> 'Processor': """ def fetch_results( - request: 'ElectionDayRequest', - app: 'ElectionDayApp' + request: ElectionDayRequest, + app: ElectionDayApp ) -> None: if not app.principal: return @@ -110,11 +112,11 @@ def fetch_results( @click.option('--originator') @pass_group_context def send_sms( - group_context: 'GroupContext', + group_context: GroupContext, username: str, password: str, originator: str | None -) -> 'Processor': +) -> Processor: r""" Sends the SMS in the smsdir for a given instance. For example: .. code-block:: bash @@ -125,8 +127,8 @@ def send_sms( """ def send( - request: 'ElectionDayRequest', - app: 'ElectionDayApp' + request: ElectionDayRequest, + app: ElectionDayApp ) -> None: if 'sms_directory' in app.configuration: path = os.path.join(app.configuration['sms_directory'], app.schema) @@ -143,7 +145,7 @@ def send( @cli.command('generate-media') -def generate_media() -> 'Processor': +def generate_media() -> Processor: """ Generates the PDF and/or SVGs for the selected instances. For example: .. code-block:: bash @@ -152,7 +154,7 @@ def generate_media() -> 'Processor': """ - def generate(request: 'ElectionDayRequest', app: 'ElectionDayApp') -> None: + def generate(request: ElectionDayRequest, app: ElectionDayApp) -> None: if not app.principal or not app.configuration.get('d3_renderer'): return @@ -169,13 +171,13 @@ def generate(request: 'ElectionDayRequest', app: 'ElectionDayApp') -> None: @cli.command('generate-archive') -def generate_archive() -> 'Processor': +def generate_archive() -> Processor: """ Generates a zipped file of the entire archive. .. code-block:: bash onegov-election-day --select '/onegov_election_day/zg' generate-archive """ - def generate(request: 'ElectionDayRequest', app: 'ElectionDayApp') -> None: + def generate(request: ElectionDayRequest, app: ElectionDayApp) -> None: click.secho('Starting archive.zip generation.') @@ -201,10 +203,10 @@ def generate(request: 'ElectionDayRequest', app: 'ElectionDayApp') -> None: @cli.command('update-archived-results') @click.option('--host', default='localhost:8080') @click.option('--scheme', default='http') -def update_archived_results(host: str, scheme: str) -> 'Processor': +def update_archived_results(host: str, scheme: str) -> Processor: """ Update the archive results, e.g. after a database transfer. """ - def generate(request: 'ElectionDayRequest', app: 'ElectionDayApp') -> None: + def generate(request: ElectionDayRequest, app: ElectionDayApp) -> None: click.secho(f'Updating {app.schema}', fg='yellow') request.host = host request.environ['wsgi.url_scheme'] = scheme @@ -215,8 +217,8 @@ def generate(request: 'ElectionDayRequest', app: 'ElectionDayApp') -> None: @cli.command('migrate-subscribers') -def migrate_subscribers() -> 'Processor': - def migrate(request: 'ElectionDayRequest', app: 'ElectionDayApp') -> None: +def migrate_subscribers() -> Processor: + def migrate(request: ElectionDayRequest, app: ElectionDayApp) -> None: if not app.principal or not app.principal.segmented_notifications: return diff --git a/src/onegov/election_day/collections/__init__.py b/src/onegov/election_day/collections/__init__.py index 1dca2c2673..ecc6a4c1ed 100644 --- a/src/onegov/election_day/collections/__init__.py +++ b/src/onegov/election_day/collections/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.collections.archived_results import \ ArchivedResultCollection from onegov.election_day.collections.archived_results import \ diff --git a/src/onegov/election_day/collections/archived_results.py b/src/onegov/election_day/collections/archived_results.py index 672f76fc9a..86c6bd1f3f 100644 --- a/src/onegov/election_day/collections/archived_results.py +++ b/src/onegov/election_day/collections/archived_results.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from datetime import date from itertools import groupby @@ -54,55 +56,55 @@ @overload def groupbydict( - items: 'Iterable[_T1]', - keyfunc: 'Callable[[_T1], _TSupportsRichComparison]', + items: Iterable[_T1], + keyfunc: Callable[[_T1], _TSupportsRichComparison], sortfunc: None = None, - groupfunc: 'Callable[[Iterable[_T1]], list[_T1]]' = list, -) -> dict['_TSupportsRichComparison', list['_T1']]: ... + groupfunc: Callable[[Iterable[_T1]], list[_T1]] = list, +) -> dict[_TSupportsRichComparison, list[_T1]]: ... @overload def groupbydict( - items: 'Iterable[_T1]', - keyfunc: 'Callable[[_T1], _T2]', - sortfunc: 'Callable[[_T1], SupportsRichComparison]', - groupfunc: 'Callable[[Iterable[_T1]], list[_T1]]' = list, -) -> dict['_T2', list['_T1']]: ... + items: Iterable[_T1], + keyfunc: Callable[[_T1], _T2], + sortfunc: Callable[[_T1], SupportsRichComparison], + groupfunc: Callable[[Iterable[_T1]], list[_T1]] = list, +) -> dict[_T2, list[_T1]]: ... @overload def groupbydict( - items: 'Iterable[_T1]', - keyfunc: 'Callable[[_T1], _TSupportsRichComparison]', + items: Iterable[_T1], + keyfunc: Callable[[_T1], _TSupportsRichComparison], sortfunc: None = None, *, - groupfunc: 'Callable[[Iterable[_T1]], _T2]', -) -> dict['_TSupportsRichComparison', '_T2']: ... + groupfunc: Callable[[Iterable[_T1]], _T2], +) -> dict[_TSupportsRichComparison, _T2]: ... @overload def groupbydict( - items: 'Iterable[_T1]', - keyfunc: 'Callable[[_T1], _TSupportsRichComparison]', + items: Iterable[_T1], + keyfunc: Callable[[_T1], _TSupportsRichComparison], sortfunc: None, - groupfunc: 'Callable[[Iterable[_T1]], _T2]', -) -> dict['_TSupportsRichComparison', '_T2']: ... + groupfunc: Callable[[Iterable[_T1]], _T2], +) -> dict[_TSupportsRichComparison, _T2]: ... @overload def groupbydict( - items: 'Iterable[_T1]', - keyfunc: 'Callable[[_T1], _T2]', - sortfunc: 'Callable[[_T1], SupportsRichComparison]', - groupfunc: 'Callable[[Iterable[_T1]], _T3]', -) -> dict['_T2', '_T3']: ... + items: Iterable[_T1], + keyfunc: Callable[[_T1], _T2], + sortfunc: Callable[[_T1], SupportsRichComparison], + groupfunc: Callable[[Iterable[_T1]], _T3], +) -> dict[_T2, _T3]: ... def groupbydict( - items: 'Iterable[_T1]', - keyfunc: 'Callable[[_T1], Any]', - sortfunc: 'Callable[[_T1], Any] | None' = None, - groupfunc: 'Callable[[Iterable[_T1]], Any]' = list + items: Iterable[_T1], + keyfunc: Callable[[_T1], Any], + sortfunc: Callable[[_T1], Any] | None = None, + groupfunc: Callable[[Iterable[_T1]], Any] = list ) -> dict[Any, Any]: return OrderedDict( @@ -116,14 +118,14 @@ def groupbydict( class ArchivedResultCollection: - def __init__(self, session: 'Session', date_: str | None = None): + def __init__(self, session: Session, date_: str | None = None): self.session = session self.date = date_ - def for_date(self, date_: str) -> 'Self': + def for_date(self, date_: str) -> Self: return self.__class__(self.session, date_) - def query(self) -> 'Query[ArchivedResult]': + def query(self) -> Query[ArchivedResult]: return self.session.query(ArchivedResult) def get_years(self) -> list[int]: @@ -137,8 +139,8 @@ def get_years(self) -> list[int]: def group_items( self, - items: 'Collection[ArchivedResult]', - request: 'ElectionDayRequest' + items: Collection[ArchivedResult], + request: ElectionDayRequest ) -> dict[date, dict[str | None, dict[str, list[ArchivedResult]]]] | None: """ Groups a list of archived results. @@ -188,7 +190,7 @@ def group_items( ) ) - def current(self) -> tuple[list[ArchivedResult], 'datetime | None']: + def current(self) -> tuple[list[ArchivedResult], datetime | None]: """ Returns the current results. The current results are the results from either the next election day @@ -212,7 +214,7 @@ def current(self) -> tuple[list[ArchivedResult], 'datetime | None']: def by_year( self, year: int - ) -> tuple[list[ArchivedResult], 'datetime | None']: + ) -> tuple[list[ArchivedResult], datetime | None]: """ Returns the results for the given year. """ query = self.query() @@ -234,7 +236,7 @@ def by_year( def by_date( self, date_: date | None = None - ) -> tuple[list[ArchivedResult], 'datetime | None']: + ) -> tuple[list[ArchivedResult], datetime | None]: """ Returns the results of a given/current date. """ if date_ is None: @@ -271,7 +273,7 @@ def by_date( def update( self, item: Election | ElectionCompound | Vote, - request: 'ElectionDayRequest', + request: ElectionDayRequest, old: str | None = None ) -> ArchivedResult: """ Updates a result. """ @@ -334,7 +336,7 @@ def update( return result - def update_all(self, request: 'ElectionDayRequest') -> None: + def update_all(self, request: ElectionDayRequest) -> None: """ Updates all (local) results. """ schema = self.session.info['schema'] @@ -354,7 +356,7 @@ def update_all(self, request: 'ElectionDayRequest') -> None: def add( self, item: Election | ElectionCompound | Vote, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: """ Add a new election or vote and create a result entry. """ @@ -369,7 +371,7 @@ def add( def clear_results( self, item: Election | ElectionCompound | Vote, - request: 'ElectionDayRequest', + request: ElectionDayRequest, clear_all: bool = False ) -> None: """ Clears the result of an election or vote. """ @@ -386,7 +388,7 @@ def clear_results( def delete( self, item: Election | ElectionCompound | Vote, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: """ Deletes an election or vote and the associated result entry. """ @@ -410,7 +412,7 @@ class SearchableArchivedResultCollection( def __init__( self, - app: 'ElectionDayApp', + app: ElectionDayApp, date_: str | None = None, from_date: date | None = None, to_date: date | None = None, @@ -435,14 +437,14 @@ def __init__( def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) and self.page == other.page - def subset(self) -> 'Query[ArchivedResult]': + def subset(self) -> Query[ArchivedResult]: return self.query() @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__( app=self.app, date_=self.date, @@ -475,10 +477,10 @@ def cleanup(word: str, whitelist_chars: str = ',.-_') -> str: @staticmethod def match_term( - column: 'ColumnElement[Any]', + column: ColumnElement[Any], language: str, term: str - ) -> 'ColumnElement[TSVECTOR | None]': + ) -> ColumnElement[TSVECTOR | None]: """ Generate a clause element for a given search term. Usage:: @@ -491,10 +493,10 @@ def match_term( @staticmethod def filter_text_by_locale( - column: 'ColumnElement[Any]', + column: ColumnElement[Any], term: str, locale: str = 'en' - ) -> 'ColumnElement[TSVECTOR | None]': + ) -> ColumnElement[TSVECTOR | None]: """ Returns an SQLAlchemy filter statement based on the search term. If no locale is provided, it will use english as language. @@ -522,8 +524,8 @@ def filter_text_by_locale( @property def term_filter(self) -> tuple[ - 'ColumnElement[TSVECTOR | None]', - 'ColumnElement[TSVECTOR | None]' + ColumnElement[TSVECTOR | None], + ColumnElement[TSVECTOR | None] ]: term = SearchableArchivedResultCollection.term_to_tsquery_string( self.term @@ -537,7 +539,7 @@ def term_filter(self) -> tuple[ ) ) - def query(self) -> 'Query[ArchivedResult]': + def query(self) -> Query[ArchivedResult]: query = self.session.query(ArchivedResult) if self.item_type: @@ -622,7 +624,7 @@ def reset_query_params(self) -> None: @classmethod def for_item_type( cls, - app: 'ElectionDayApp', + app: ElectionDayApp, item_type: Literal['vote', 'election'], *, date_: str | None = None, @@ -633,13 +635,13 @@ def for_item_type( answers: list[str] | None = None, locale: str = 'de_CH', page: int = 0 - ) -> 'Self': ... + ) -> Self: ... @overload @classmethod def for_item_type( cls, - app: 'ElectionDayApp', + app: ElectionDayApp, item_type: str | None, *, date_: str | None = None, @@ -650,12 +652,12 @@ def for_item_type( answers: list[str] | None = None, locale: str = 'de_CH', page: int = 0 - ) -> 'Self | None': ... + ) -> Self | None: ... @classmethod def for_item_type( cls, - app: 'ElectionDayApp', + app: ElectionDayApp, item_type: str | None, *, date_: str | None = None, @@ -666,7 +668,7 @@ def for_item_type( answers: list[str] | None = None, locale: str = 'de_CH', page: int = 0 - ) -> 'Self | None': + ) -> Self | None: if item_type in ('vote', 'election'): return cls( app, diff --git a/src/onegov/election_day/collections/ballots.py b/src/onegov/election_day/collections/ballots.py index a512a7f2db..635714077a 100644 --- a/src/onegov/election_day/collections/ballots.py +++ b/src/onegov/election_day/collections/ballots.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models import Ballot @@ -9,11 +11,11 @@ class BallotCollection: - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session - def query(self) -> 'Query[Ballot]': + def query(self) -> Query[Ballot]: return self.session.query(Ballot) - def by_id(self, id: 'UUID') -> Ballot | None: + def by_id(self, id: UUID) -> Ballot | None: return self.query().filter(Ballot.id == id).first() diff --git a/src/onegov/election_day/collections/candidates.py b/src/onegov/election_day/collections/candidates.py index 6dafb4e29e..8f19bc0871 100644 --- a/src/onegov/election_day/collections/candidates.py +++ b/src/onegov/election_day/collections/candidates.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models import Candidate @@ -9,11 +11,11 @@ class CandidateCollection: - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session - def query(self) -> 'Query[Candidate]': + def query(self) -> Query[Candidate]: return self.session.query(Candidate) - def by_id(self, id: 'UUID') -> Candidate | None: + def by_id(self, id: UUID) -> Candidate | None: return self.query().filter(Candidate.id == id).first() diff --git a/src/onegov/election_day/collections/data_sources.py b/src/onegov/election_day/collections/data_sources.py index 2ea845b62e..fa38e6f4e7 100644 --- a/src/onegov/election_day/collections/data_sources.py +++ b/src/onegov/election_day/collections/data_sources.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sqlalchemy import desc from onegov.core.collection import Pagination @@ -17,28 +19,28 @@ class DataSourceCollection(Pagination[DataSource]): page: int - def __init__(self, session: 'Session', page: int = 0): + def __init__(self, session: Session, page: int = 0): super().__init__(page) self.session = session def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) and self.page == other.page - def subset(self) -> 'Query[DataSource]': + def subset(self) -> Query[DataSource]: return self.query() @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__(self.session, index) - def query(self) -> 'Query[DataSource]': + def query(self) -> Query[DataSource]: return self.session.query(DataSource).order_by( desc(DataSource.created)) - def by_id(self, id: 'UUID') -> DataSource | None: + def by_id(self, id: UUID) -> DataSource | None: return self.query().filter(DataSource.id == id).first() def add(self, source: DataSource) -> None: @@ -56,8 +58,8 @@ class DataSourceItemCollection(Pagination[DataSourceItem]): def __init__( self, - session: 'Session', - id: 'UUID | None' = None, + session: Session, + id: UUID | None = None, page: int = 0 ): super().__init__(page) @@ -67,23 +69,23 @@ def __init__( def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) and self.page == other.page - def subset(self) -> 'Query[DataSourceItem]': + def subset(self) -> Query[DataSourceItem]: return self.query() @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__(self.session, self.id, index) - def query(self) -> 'Query[DataSourceItem]': + def query(self) -> Query[DataSourceItem]: query = self.session.query(DataSourceItem) query = query.filter(DataSourceItem.source_id == self.id) query = query.order_by(DataSourceItem.district, DataSourceItem.number) return query - def by_id(self, id: 'UUID') -> DataSourceItem | None: + def by_id(self, id: UUID) -> DataSourceItem | None: query = self.session.query(DataSourceItem) query = query.filter(DataSourceItem.id == id) return query.first() diff --git a/src/onegov/election_day/collections/election_compounds.py b/src/onegov/election_day/collections/election_compounds.py index 5a3b8dbaba..c2081feffb 100644 --- a/src/onegov/election_day/collections/election_compounds.py +++ b/src/onegov/election_day/collections/election_compounds.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.collection import Pagination from onegov.election_day.models import ElectionCompound from sqlalchemy import cast @@ -20,7 +22,7 @@ class ElectionCompoundCollection(Pagination[ElectionCompound]): def __init__( self, - session: 'Session', + session: Session, page: int = 0, year: int | None = None ): @@ -34,7 +36,7 @@ def __eq__(self, other: object) -> bool: return self.year == other.year and self.page == other.page - def subset(self) -> 'Query[ElectionCompound]': + def subset(self) -> Query[ElectionCompound]: query = self.query() query = query.order_by( desc(ElectionCompound.date), @@ -52,13 +54,13 @@ def subset(self) -> 'Query[ElectionCompound]': def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__(self.session, index, self.year) - def for_year(self, year: int | None) -> 'Self': + def for_year(self, year: int | None) -> Self: return self.__class__(self.session, 0, year) - def query(self) -> 'Query[ElectionCompound]': + def query(self) -> Query[ElectionCompound]: return self.session.query(ElectionCompound) def get_latest(self) -> list[ElectionCompound] | None: @@ -80,7 +82,7 @@ def get_years(self) -> list[int]: return [year for year, in query] - def by_date(self, date: 'date') -> list[ElectionCompound]: + def by_date(self, date: date) -> list[ElectionCompound]: """ Returns the election compounds on the given date. """ query = self.query() diff --git a/src/onegov/election_day/collections/elections.py b/src/onegov/election_day/collections/elections.py index 4815857073..ebe983e469 100644 --- a/src/onegov/election_day/collections/elections.py +++ b/src/onegov/election_day/collections/elections.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.collection import Pagination from onegov.election_day.models import Election from sqlalchemy import cast @@ -20,7 +22,7 @@ class ElectionCollection(Pagination[Election]): def __init__( self, - session: 'Session', + session: Session, page: int = 0, year: int | None = None ): @@ -33,7 +35,7 @@ def __eq__(self, other: object) -> bool: return False return self.year == other.year and self.page == other.page - def subset(self) -> 'Query[Election]': + def subset(self) -> Query[Election]: query = self.query() query = query.order_by( desc(Election.date), Election.shortcode, Election.title @@ -47,13 +49,13 @@ def subset(self) -> 'Query[Election]': def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__(self.session, index, self.year) - def for_year(self, year: int | None) -> 'Self': + def for_year(self, year: int | None) -> Self: return self.__class__(self.session, 0, year) - def query(self) -> 'Query[Election]': + def query(self) -> Query[Election]: return self.session.query(Election) def get_latest(self) -> list[Election] | None: @@ -75,7 +77,7 @@ def get_years(self) -> list[int]: return [year for year, in query] - def by_date(self, date: 'date') -> list[Election]: + def by_date(self, date: date) -> list[Election]: """ Returns the elections on the given date. """ query = self.query() diff --git a/src/onegov/election_day/collections/lists.py b/src/onegov/election_day/collections/lists.py index 6047cbf564..a2114cdaa0 100644 --- a/src/onegov/election_day/collections/lists.py +++ b/src/onegov/election_day/collections/lists.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models import List @@ -9,11 +11,11 @@ class ListCollection: - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session - def query(self) -> 'Query[List]': + def query(self) -> Query[List]: return self.session.query(List) - def by_id(self, id: 'UUID') -> List | None: + def by_id(self, id: UUID) -> List | None: return self.query().filter(List.id == id).first() diff --git a/src/onegov/election_day/collections/notifications.py b/src/onegov/election_day/collections/notifications.py index 027f95adaa..0aa0edc927 100644 --- a/src/onegov/election_day/collections/notifications.py +++ b/src/onegov/election_day/collections/notifications.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from itertools import chain from onegov.election_day import _ from onegov.election_day.models import Election @@ -21,10 +23,10 @@ class NotificationCollection: - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session - def query(self) -> 'Query[Notification]': + def query(self) -> Query[Notification]: return self.session.query(Notification) def by_model( @@ -58,9 +60,9 @@ def by_model( def trigger( self, - request: 'ElectionDayRequest', + request: ElectionDayRequest, model: Election | ElectionCompound | Vote, - options: 'Collection[str]' + options: Collection[str] ) -> None: """ Triggers and adds the selected notifications. """ @@ -85,11 +87,11 @@ def trigger( def trigger_summarized( self, - request: 'ElectionDayRequest', - elections: 'Sequence[Election]', - election_compounds: 'Sequence[ElectionCompound]', - votes: 'Sequence[Vote]', - options: 'Collection[str]' + request: ElectionDayRequest, + elections: Sequence[Election], + election_compounds: Sequence[ElectionCompound], + votes: Sequence[Vote], + options: Collection[str] ) -> None: """ Triggers and adds a single notification for all given votes and elections. diff --git a/src/onegov/election_day/collections/screens.py b/src/onegov/election_day/collections/screens.py index 51a163af5b..72a4843377 100644 --- a/src/onegov/election_day/collections/screens.py +++ b/src/onegov/election_day/collections/screens.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.collection import Pagination from onegov.election_day.models import Screen @@ -14,24 +16,24 @@ class ScreenCollection(Pagination[Screen]): page: int - def __init__(self, session: 'Session', page: int = 0): + def __init__(self, session: Session, page: int = 0): super().__init__(page) self.session = session def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) and self.page == other.page - def subset(self) -> 'Query[Screen]': + def subset(self) -> Query[Screen]: return self.query() @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__(self.session, index) - def query(self) -> 'Query[Screen]': + def query(self) -> Query[Screen]: return self.session.query(Screen).order_by(Screen.number) def by_id(self, id: int) -> Screen | None: diff --git a/src/onegov/election_day/collections/subscribers.py b/src/onegov/election_day/collections/subscribers.py index 93b0281881..977333af24 100644 --- a/src/onegov/election_day/collections/subscribers.py +++ b/src/onegov/election_day/collections/subscribers.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from email.headerregistry import Address from onegov.core.collection import Pagination from onegov.core.templates import render_template @@ -31,8 +33,8 @@ class SubscriberCollection(Pagination[_S]): page: int def __init__( - self: 'SubscriberCollection[Subscriber]', - session: 'Session', + self: SubscriberCollection[Subscriber], + session: Session, page: int = 0, term: str | None = None, active_only: bool | None = True @@ -54,17 +56,17 @@ def __eq__(self, other: object) -> bool: and self.active_only == other.active_only ) - def subset(self) -> 'Query[_S]': + def subset(self) -> Query[_S]: return self.query() @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__(self.session, index) - def for_active_only(self, active_only: bool) -> 'Self': + def for_active_only(self, active_only: bool) -> Self: return self.__class__(self.session, 0, self.term, active_only) def add( @@ -86,7 +88,7 @@ def add( self.session.flush() return subscriber - def query(self, active_only: bool | None = None) -> 'Query[_S]': + def query(self, active_only: bool | None = None) -> Query[_S]: query = self.session.query(self.model_class) active_only = self.active_only if active_only is None else active_only @@ -101,7 +103,7 @@ def query(self, active_only: bool | None = None) -> 'Query[_S]': return query - def by_id(self, id: 'UUID') -> _S | None: + def by_id(self, id: UUID) -> _S | None: """ Returns the subscriber by its id. """ query = self.query(active_only=False) @@ -129,7 +131,7 @@ def initiate_subscription( address: str, domain: str | None, domain_segment: str | None, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> _S: """ Initiate the subscription process. @@ -154,7 +156,7 @@ def handle_subscription( subscriber: _S, domain: str | None, domain_segment: str | None, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: """ Send the subscriber a request to confirm the subscription. """ @@ -165,7 +167,7 @@ def initiate_unsubscription( address: str, domain: str | None, domain_segment: str | None, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: """ Initiate the unsubscription process. """ @@ -176,7 +178,7 @@ def initiate_unsubscription( def handle_unsubscription( self, subscriber: _S, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: """ Send the subscriber a request to confirm the unsubscription. """ @@ -203,7 +205,7 @@ def cleanup( file: IO[bytes], mimetype: str, delete: bool - ) -> tuple[list['FileImportError'], int]: + ) -> tuple[list[FileImportError], int]: """ Disables or deletes the subscribers in the given CSV. Ignores domain and domain segment, as this is inteded to cleanup @@ -242,7 +244,7 @@ def handle_subscription( subscriber: EmailSubscriber, domain: str | None, domain_segment: str | None, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: """ Send the (new) subscriber a request to confirm the subscription. @@ -312,7 +314,7 @@ def confirm_subscription( def handle_unsubscription( self, subscriber: EmailSubscriber, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: """ Send the subscriber a request to confirm the unsubscription. """ @@ -383,7 +385,7 @@ def handle_subscription( subscriber: SmsSubscriber, domain: str | None, domain_segment: str | None, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: """ Confirm the subscription by sending an SMS (if not already subscribed). There is no double-opt-in for SMS subscribers. @@ -406,7 +408,7 @@ def handle_subscription( def handle_unsubscription( self, subscriber: SmsSubscriber, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: """ Deactivate the subscriber. There is no double-opt-out for SMS subscribers. diff --git a/src/onegov/election_day/collections/upload_tokens.py b/src/onegov/election_day/collections/upload_tokens.py index 5670205403..b1267895e8 100644 --- a/src/onegov/election_day/collections/upload_tokens.py +++ b/src/onegov/election_day/collections/upload_tokens.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models import UploadToken @@ -10,10 +12,10 @@ class UploadTokenCollection: - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session - def query(self) -> 'Query[UploadToken]': + def query(self) -> Query[UploadToken]: return self.session.query(UploadToken).order_by(UploadToken.created) def create(self) -> UploadToken: @@ -30,7 +32,7 @@ def delete(self, item: UploadToken) -> None: self.session.delete(item) self.session.flush() - def by_id(self, id: 'UUID') -> UploadToken | None: + def by_id(self, id: UUID) -> UploadToken | None: """ Returns the token by its id. """ return self.query().filter_by(id=id).first() diff --git a/src/onegov/election_day/collections/votes.py b/src/onegov/election_day/collections/votes.py index ca070bc6c8..06d77b9747 100644 --- a/src/onegov/election_day/collections/votes.py +++ b/src/onegov/election_day/collections/votes.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.collection import Pagination from onegov.election_day.models import Vote from sqlalchemy import cast @@ -20,7 +22,7 @@ class VoteCollection(Pagination[Vote]): def __init__( self, - session: 'Session', + session: Session, page: int = 0, year: int | None = None ): @@ -33,7 +35,7 @@ def __eq__(self, other: object) -> bool: return False return self.year == other.year and self.page == other.page - def subset(self) -> 'Query[Vote]': + def subset(self) -> Query[Vote]: query = self.query() query = query.order_by(desc(Vote.date), Vote.shortcode, Vote.title) if self.year: @@ -45,13 +47,13 @@ def subset(self) -> 'Query[Vote]': def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__(self.session, index, self.year) - def for_year(self, year: int | None) -> 'Self': + def for_year(self, year: int | None) -> Self: return self.__class__(self.session, 0, year) - def query(self) -> 'Query[Vote]': + def query(self) -> Query[Vote]: return self.session.query(Vote) def get_latest(self) -> list[Vote] | None: @@ -71,7 +73,7 @@ def get_years(self) -> list[int]: return [year for year, in query] - def by_date(self, date: 'date') -> list[Vote]: + def by_date(self, date: date) -> list[Vote]: """ Returns the votes on the given date. """ query = self.query() diff --git a/src/onegov/election_day/directives.py b/src/onegov/election_day/directives.py index a93433ae7f..77428627e6 100644 --- a/src/onegov/election_day/directives.py +++ b/src/onegov/election_day/directives.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from dectate import Action from morepath.directive import HtmlAction from morepath.directive import ViewAction @@ -50,9 +52,9 @@ class ManageHtmlAction(HtmlAction): def __init__( self, model: type | str, - render: 'Callable[[Any, _RequestT], BaseResponse] | str | None' = None, - template: 'StrOrBytesPath | None' = None, - load: 'Callable[[_RequestT], Any] | str | None' = None, + render: Callable[[Any, _RequestT], BaseResponse] | str | None = None, + template: StrOrBytesPath | None = None, + load: Callable[[_RequestT], Any] | str | None = None, permission: object | str | None = None, internal: bool = False, **predicates: Any, @@ -79,10 +81,10 @@ class ManageFormAction(HtmlHandleFormAction): def __init__( self, model: type | str, - form: 'type[Form] | FormCallable[_RequestT]' = EmptyForm, - render: 'Callable[[Any, _RequestT], BaseResponse] | str | None' = None, - template: 'StrOrBytesPath' = 'form.pt', - load: 'Callable[[_RequestT], Any] | str | None' = None, + form: type[Form] | FormCallable[_RequestT] = EmptyForm, + render: Callable[[Any, _RequestT], BaseResponse] | str | None = None, + template: StrOrBytesPath = 'form.pt', + load: Callable[[_RequestT], Any] | str | None = None, permission: object | str | None = None, internal: bool = False, **predicates: Any, @@ -100,7 +102,7 @@ def __init__( ) -def render_svg(content: dict[str, Any], request: 'CoreRequest') -> Response: +def render_svg(content: dict[str, Any], request: CoreRequest) -> Response: path = content.get('path') name = content.get('name') if not path: @@ -119,7 +121,7 @@ def render_svg(content: dict[str, Any], request: 'CoreRequest') -> Response: ) -def render_pdf(content: dict[str, Any], request: 'CoreRequest') -> Response: +def render_pdf(content: dict[str, Any], request: CoreRequest) -> Response: path = content.get('path') name = content.get('name') if not path: @@ -138,7 +140,7 @@ def render_pdf(content: dict[str, Any], request: 'CoreRequest') -> Response: ) -def render_json(content: dict[str, Any], request: 'CoreRequest') -> Response: +def render_json(content: dict[str, Any], request: CoreRequest) -> Response: data = content.get('data', {}) name = content.get('name', 'data') return Response( @@ -147,7 +149,7 @@ def render_json(content: dict[str, Any], request: 'CoreRequest') -> Response: content_disposition=f'inline; filename={name}.json') -def render_csv(content: dict[str, Any], request: 'CoreRequest') -> Response: +def render_csv(content: dict[str, Any], request: CoreRequest) -> Response: data = content.get('data', {}) name = content.get('name', 'data') return Response( @@ -165,7 +167,7 @@ class SvgFileViewAction(ViewAction): def __init__( self, model: type | str, - load: 'Callable[[_RequestT], Any] | str | None' = None, + load: Callable[[_RequestT], Any] | str | None = None, permission: object | str = Public, internal: bool = False, **predicates: Any, @@ -190,7 +192,7 @@ class PdfFileViewAction(ViewAction): def __init__( self, model: type | str, - load: 'Callable[[_RequestT], Any] | str | None' = None, + load: Callable[[_RequestT], Any] | str | None = None, permission: object | str = Public, internal: bool = False, **predicates: Any, @@ -214,7 +216,7 @@ class JsonFileAction(ViewAction): def __init__( self, model: type | str, - load: 'Callable[[_RequestT], Any] | str | None' = None, + load: Callable[[_RequestT], Any] | str | None = None, permission: object | str = Public, internal: bool = False, **predicates: Any, @@ -238,7 +240,7 @@ class CsvFileAction(ViewAction): def __init__( self, model: type | str, - load: 'Callable[[_RequestT], Any] | str | None' = None, + load: Callable[[_RequestT], Any] | str | None = None, permission: object | str = Public, internal: bool = False, **predicates: Any, @@ -259,8 +261,8 @@ class ScreenWidgetRegistry(dict[str, dict[str, 'ScreenWidget']]): def by_categories( self, - categories: 'Iterable[str]' - ) -> dict[str, 'ScreenWidget']: + categories: Iterable[str] + ) -> dict[str, ScreenWidget]: result: dict[str, ScreenWidget] = {} for category in categories: @@ -287,7 +289,7 @@ def identifier( # type:ignore[override] def perform( # type:ignore[override] self, - func: 'Callable[[], InputScreenWidget]', + func: Callable[[], InputScreenWidget], screen_widget_registry: ScreenWidgetRegistry ) -> None: diff --git a/src/onegov/election_day/formats/__init__.py b/src/onegov/election_day/formats/__init__.py index 1803509e13..3730cd6959 100644 --- a/src/onegov/election_day/formats/__init__.py +++ b/src/onegov/election_day/formats/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.exports import ( export_election_compound_internal) from onegov.election_day.formats.exports import export_election_internal diff --git a/src/onegov/election_day/formats/exports/__init__.py b/src/onegov/election_day/formats/exports/__init__.py index 76c8fd5cab..60a8996401 100644 --- a/src/onegov/election_day/formats/exports/__init__.py +++ b/src/onegov/election_day/formats/exports/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.exports.election import \ export_election_internal from onegov.election_day.formats.exports.election import \ @@ -22,7 +24,7 @@ def export_internal( item: Election | ElectionCompound | Vote, - locales: 'Collection[str]' + locales: Collection[str] ) -> list[dict[str, Any]]: if isinstance(item, Vote): diff --git a/src/onegov/election_day/formats/exports/election/__init__.py b/src/onegov/election_day/formats/exports/election/__init__.py index 8718117f38..5ff1dcbe88 100644 --- a/src/onegov/election_day/formats/exports/election/__init__.py +++ b/src/onegov/election_day/formats/exports/election/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.exports.election.internal_majorz import \ export_election_internal_majorz from onegov.election_day.formats.exports.election.internal_proporz import \ @@ -12,8 +14,8 @@ def export_election_internal( - election: 'Election', - locales: 'Collection[str]' + election: Election, + locales: Collection[str] ) -> list[dict[str, Any]]: if election.type == 'proporz': diff --git a/src/onegov/election_day/formats/exports/election/internal_majorz.py b/src/onegov/election_day/formats/exports/election/internal_majorz.py index 6b79657081..96df4700ea 100644 --- a/src/onegov/election_day/formats/exports/election/internal_majorz.py +++ b/src/onegov/election_day/formats/exports/election/internal_majorz.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from onegov.election_day.models import Candidate from onegov.election_day.models import CandidateResult @@ -14,7 +16,7 @@ def export_election_internal_majorz( election: Election, - locales: 'Collection[str]' + locales: Collection[str] ) -> list[dict[str, Any]]: """ Returns all data connected to this election as list with dicts. diff --git a/src/onegov/election_day/formats/exports/election/internal_proporz.py b/src/onegov/election_day/formats/exports/election/internal_proporz.py index 1cde9d41aa..0108aa9fa2 100644 --- a/src/onegov/election_day/formats/exports/election/internal_proporz.py +++ b/src/onegov/election_day/formats/exports/election/internal_proporz.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from itertools import groupby from onegov.election_day.models import Candidate @@ -21,7 +23,7 @@ def export_election_internal_proporz( election: Election, - locales: 'Collection[str]' + locales: Collection[str] ) -> list[dict[str, Any]]: """ Returns all data connected to this election as list with dicts. diff --git a/src/onegov/election_day/formats/exports/election_compound/__init__.py b/src/onegov/election_day/formats/exports/election_compound/__init__.py index 1e96c1f38a..dd03513d56 100644 --- a/src/onegov/election_day/formats/exports/election_compound/__init__.py +++ b/src/onegov/election_day/formats/exports/election_compound/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.exports.election_compound.internal import ( export_election_compound_internal) diff --git a/src/onegov/election_day/formats/exports/election_compound/internal.py b/src/onegov/election_day/formats/exports/election_compound/internal.py index e2d7b09015..1d0a3aced9 100644 --- a/src/onegov/election_day/formats/exports/election_compound/internal.py +++ b/src/onegov/election_day/formats/exports/election_compound/internal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from itertools import chain from onegov.election_day.formats.exports.election import ( @@ -12,8 +14,8 @@ def export_election_compound_internal( - compound: 'ElectionCompound', - locales: 'Collection[str]' + compound: ElectionCompound, + locales: Collection[str] ) -> list[dict[str, Any]]: """ Returns all data connected to this election compound as list with dicts. diff --git a/src/onegov/election_day/formats/exports/party_result/__init__.py b/src/onegov/election_day/formats/exports/party_result/__init__.py index 80bc0bdd87..9538935c8e 100644 --- a/src/onegov/election_day/formats/exports/party_result/__init__.py +++ b/src/onegov/election_day/formats/exports/party_result/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.exports.party_result.internal import ( export_parties_internal) diff --git a/src/onegov/election_day/formats/exports/party_result/internal.py b/src/onegov/election_day/formats/exports/party_result/internal.py index 7df665b4d9..4f47135432 100644 --- a/src/onegov/election_day/formats/exports/party_result/internal.py +++ b/src/onegov/election_day/formats/exports/party_result/internal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict @@ -11,8 +13,8 @@ def export_parties_internal( - item: 'ElectionCompound | ProporzElection', - locales: 'Collection[str]', + item: ElectionCompound | ProporzElection, + locales: Collection[str], default_locale: str, json_serializable: bool = False ) -> list[dict[str, Any]]: @@ -45,8 +47,8 @@ def export_parties_internal( def _export_parties( - item: 'ElectionCompound | ProporzElection', - locales: 'Collection[str]', + item: ElectionCompound | ProporzElection, + locales: Collection[str], default_locale: str, json_serializable: bool = False, domain: str | None = None, @@ -66,7 +68,7 @@ def _export_parties( """ - def convert_decimal(value: 'Decimal | None') -> float | str | None: + def convert_decimal(value: Decimal | None) -> float | str | None: if value is None: return value if json_serializable: diff --git a/src/onegov/election_day/formats/exports/vote/__init__.py b/src/onegov/election_day/formats/exports/vote/__init__.py index cacbf81c4e..2f37318c90 100644 --- a/src/onegov/election_day/formats/exports/vote/__init__.py +++ b/src/onegov/election_day/formats/exports/vote/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.exports.vote.internal import ( export_vote_internal) diff --git a/src/onegov/election_day/formats/exports/vote/internal.py b/src/onegov/election_day/formats/exports/vote/internal.py index b729f5d381..c086ee6365 100644 --- a/src/onegov/election_day/formats/exports/vote/internal.py +++ b/src/onegov/election_day/formats/exports/vote/internal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict @@ -9,8 +11,8 @@ def export_vote_internal( - vote: 'Vote', - locales: 'Collection[str]' + vote: Vote, + locales: Collection[str] ) -> list[dict[str, Any]]: """ Returns all data connected to this vote as list with dicts. diff --git a/src/onegov/election_day/formats/imports/__init__.py b/src/onegov/election_day/formats/imports/__init__.py index 762291c96f..afa20a7193 100644 --- a/src/onegov/election_day/formats/imports/__init__.py +++ b/src/onegov/election_day/formats/imports/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.imports.ech import import_ech from onegov.election_day.formats.imports.election_compound import ( import_election_compound_internal) diff --git a/src/onegov/election_day/formats/imports/common.py b/src/onegov/election_day/formats/imports/common.py index dbf38e95fb..7258e8e3af 100644 --- a/src/onegov/election_day/formats/imports/common.py +++ b/src/onegov/election_day/formats/imports/common.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from decimal import Decimal from onegov.core.csv import convert_excel_to_csv from onegov.core.csv import CSVFile @@ -75,13 +77,13 @@ ) -STATI: tuple['Status', ...] = ( +STATI: tuple[Status, ...] = ( 'unknown', 'interim', 'final', ) -BALLOT_TYPES: set['BallotType'] = { +BALLOT_TYPES: set[BallotType] = { 'proposal', 'counter-proposal', 'tie-breaker' @@ -119,12 +121,12 @@ def __hash__(self) -> int: def load_csv( file: IO[bytes], mimetype: str, - expected_headers: 'Sequence[str] | None', + expected_headers: Sequence[str] | None, filename: str | None = None, - dialect: 'type[Dialect] | Dialect | str | None' = None, + dialect: type[Dialect] | Dialect | str | None = None, encoding: str | None = None, rename_duplicate_column_names: bool = False -) -> tuple['DefaultCSVFile | None', FileImportError | None]: +) -> tuple[DefaultCSVFile | None, FileImportError | None]: """ Loads the given file and returns it as CSV file. :return: A tuple CSVFile, FileImportError. @@ -258,8 +260,8 @@ def load_xml( def get_entity_and_district( entity_id: int, entities: dict[int, dict[str, str]], - election_or_vote: 'Election | Vote', - principal: 'Canton | Municipality', + election_or_vote: Election | Vote, + principal: Canton | Municipality, errors: list[str] | None = None ) -> tuple[str, str, str]: """ Returns the entity name and district or region (from our static data, @@ -303,7 +305,7 @@ def get_entity_and_district( def line_is_relevant( - line: 'DefaultRow', + line: DefaultRow, number: str, district: str | None = None ) -> bool: @@ -314,7 +316,7 @@ def line_is_relevant( @overload def validate_integer( - line: 'DefaultRow', + line: DefaultRow, col: str, treat_none_as_default: bool = True, default: int = 0, @@ -324,7 +326,7 @@ def validate_integer( @overload def validate_integer( - line: 'DefaultRow', + line: DefaultRow, col: str, treat_none_as_default: bool, default: _T, @@ -334,7 +336,7 @@ def validate_integer( @overload def validate_integer( - line: 'DefaultRow', + line: DefaultRow, col: str, treat_none_as_default: bool = True, *, @@ -344,7 +346,7 @@ def validate_integer( def validate_integer( - line: 'DefaultRow', + line: DefaultRow, col: str, treat_none_as_default: bool = True, default: int | _T = 0, @@ -379,7 +381,7 @@ def validate_integer( @overload def validate_numeric( - line: 'DefaultRow', + line: DefaultRow, col: str, precision: int, scale: int, @@ -391,7 +393,7 @@ def validate_numeric( @overload def validate_numeric( - line: 'DefaultRow', + line: DefaultRow, col: str, precision: int, scale: int, @@ -403,7 +405,7 @@ def validate_numeric( @overload def validate_numeric( - line: 'DefaultRow', + line: DefaultRow, col: str, precision: int, scale: int, @@ -415,7 +417,7 @@ def validate_numeric( def validate_numeric( - line: 'DefaultRow', + line: DefaultRow, col: str, precision: int, scale: int, @@ -455,7 +457,7 @@ def validate_numeric( @overload def validate_list_id( - line: 'DefaultRow', + line: DefaultRow, col: str, treat_empty_as_default: bool = True, default: str = '0' @@ -464,7 +466,7 @@ def validate_list_id( @overload def validate_list_id( - line: 'DefaultRow', + line: DefaultRow, col: str, treat_empty_as_default: bool, default: _T @@ -473,7 +475,7 @@ def validate_list_id( @overload def validate_list_id( - line: 'DefaultRow', + line: DefaultRow, col: str, treat_empty_as_default: bool = True, *, @@ -482,7 +484,7 @@ def validate_list_id( def validate_list_id( - line: 'DefaultRow', + line: DefaultRow, col: str, treat_empty_as_default: bool = True, default: str | _T = '0' @@ -503,7 +505,7 @@ def validate_list_id( raise ValueError(_('Empty value: ${col}', mapping={'col': col})) -def validate_gender(line: 'DefaultRow') -> 'Gender | None': +def validate_gender(line: DefaultRow) -> Gender | None: result = getattr(line, 'candidate_gender', None) or None if result not in (None, 'male', 'female', 'undetermined'): raise ValueError( @@ -512,7 +514,7 @@ def validate_gender(line: 'DefaultRow') -> 'Gender | None': return result -def validate_color(line: 'DefaultRow', col: str) -> str: +def validate_color(line: DefaultRow, col: str) -> str: result = getattr(line, col, '') or '' if result and not match(r'^#[0-9A-Fa-f]{6}$', result): raise ValueError( @@ -523,9 +525,9 @@ def validate_color(line: 'DefaultRow', col: str) -> str: def convert_ech_domain( domain: DomainOfInfluenceType, - principal: 'Canton | Municipality', + principal: Canton | Municipality, entities: dict[int, dict[str, str]], -) -> tuple[bool, 'DomainOfInfluence', str]: +) -> tuple[bool, DomainOfInfluence, str]: """ Convert the given eCH domain to our internal domain and domain segment. diff --git a/src/onegov/election_day/formats/imports/ech.py b/src/onegov/election_day/formats/imports/ech.py index aca965b65c..a9f402457d 100644 --- a/src/onegov/election_day/formats/imports/ech.py +++ b/src/onegov/election_day/formats/imports/ech.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.formats.imports.common import FileImportError from onegov.election_day.formats.imports.common import load_xml @@ -17,11 +19,11 @@ def import_ech( - principal: 'Canton | Municipality', + principal: Canton | Municipality, file: IO[bytes], - session: 'Session', + session: Session, default_locale: str -) -> 'ECHImportResultType': +) -> ECHImportResultType: """ Tries to import the given eCH XML file. This function is typically called automatically every few minutes during @@ -44,7 +46,7 @@ def import_ech( updated = set() deleted = set() - def unwrap(result: 'ECHImportResultType') -> None: + def unwrap(result: ECHImportResultType) -> None: errors.extend(result[0]) updated.update(result[1]) deleted.update(result[2]) diff --git a/src/onegov/election_day/formats/imports/election/__init__.py b/src/onegov/election_day/formats/imports/election/__init__.py index 5d46ff2063..e82a352e70 100644 --- a/src/onegov/election_day/formats/imports/election/__init__.py +++ b/src/onegov/election_day/formats/imports/election/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.imports.election.ech import ( import_elections_ech) from onegov.election_day.formats.imports.election.internal_majorz import ( diff --git a/src/onegov/election_day/formats/imports/election/ech.py b/src/onegov/election_day/formats/imports/election/ech.py index 742606f5b4..259d64c701 100644 --- a/src/onegov/election_day/formats/imports/election/ech.py +++ b/src/onegov/election_day/formats/imports/election/ech.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.formats.imports.common import convert_ech_domain from onegov.election_day.formats.imports.common import EXPATS @@ -45,7 +47,7 @@ TypeOfElectionType.VALUE_2: Election, } -gender: dict[SexType, 'Gender'] = { +gender: dict[SexType, Gender] = { SexType.VALUE_1: 'male', SexType.VALUE_2: 'female', SexType.VALUE_3: 'undetermined', @@ -53,11 +55,11 @@ def import_elections_ech( - principal: 'Canton | Municipality', - delivery: 'Delivery', - session: 'Session', + principal: Canton | Municipality, + delivery: Delivery, + session: Session, default_locale: str, -) -> 'ECHImportResultType': +) -> ECHImportResultType: """ Imports all elections in a given eCH-0252 delivery. Deletes elections on the same day not appearing in the delivery. @@ -118,12 +120,12 @@ def import_elections_ech( def import_information_delivery( - principal: 'Canton | Municipality', - delivery: 'EventElectionInformationDeliveryType', - session: 'Session', + principal: Canton | Municipality, + delivery: EventElectionInformationDeliveryType, + session: Session, default_locale: str, ) -> tuple[ - 'date', + date, list[ElectionCompound], list[Election], set[ElectionCompound | Election], @@ -363,9 +365,9 @@ def import_information_delivery( def import_result_delivery( - principal: 'Canton | Municipality', - delivery: 'EventElectionResultDeliveryType', - polling_day: 'date', + principal: Canton | Municipality, + delivery: EventElectionResultDeliveryType, + polling_day: date, elections: list[Election], errors: set[FileImportError] ) -> None: @@ -564,7 +566,7 @@ def import_result_delivery( def import_majoral_election_result( candidates: dict[str, Candidate], election_result: ElectionResult, - majoral_election: 'ElectionResultType.MajoralElection', + majoral_election: ElectionResultType.MajoralElection, errors: set[FileImportError] ) -> None: """ Helper function to import election results specific to majoral @@ -599,7 +601,7 @@ def import_proportional_election_result( candidates: dict[str, Candidate], lists: dict[str, List], election_result: ElectionResult, - proportional_election: 'ElectionResultType.ProportionalElection', + proportional_election: ElectionResultType.ProportionalElection, errors: set[FileImportError] ) -> None: """ Helper function to import election results specific to proportional diff --git a/src/onegov/election_day/formats/imports/election/internal_majorz.py b/src/onegov/election_day/formats/imports/election/internal_majorz.py index 22e235cb76..1e08d35659 100644 --- a/src/onegov/election_day/formats/imports/election/internal_majorz.py +++ b/src/onegov/election_day/formats/imports/election/internal_majorz.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.formats.imports.common import EXPATS from onegov.election_day.formats.imports.common import FileImportError @@ -49,9 +51,9 @@ def parse_election( - line: 'DefaultRow', + line: DefaultRow, errors: list[str] -) -> tuple[int | None, 'Status | None']: +) -> tuple[int | None, Status | None]: majority = None status = None @@ -72,11 +74,11 @@ def parse_election( def parse_election_result( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], entities: dict[int, dict[str, str]], - election: 'Election', - principal: 'Canton | Municipality' + election: Election, + principal: Canton | Municipality ) -> dict[str, Any] | None: try: @@ -134,7 +136,7 @@ def parse_election_result( def parse_candidate( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], election_id: str, colors: dict[str, str] @@ -173,7 +175,7 @@ def parse_candidate( def parse_candidate_result( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], counted: bool ) -> dict[str, Any] | None: @@ -191,8 +193,8 @@ def parse_candidate_result( def import_election_internal_majorz( - election: 'Election', - principal: 'Canton | Municipality', + election: Election, + principal: Canton | Municipality, file: IO[bytes], mimetype: str ) -> list[FileImportError]: diff --git a/src/onegov/election_day/formats/imports/election/internal_proporz.py b/src/onegov/election_day/formats/imports/election/internal_proporz.py index 408517d605..df2a2df99d 100644 --- a/src/onegov/election_day/formats/imports/election/internal_proporz.py +++ b/src/onegov/election_day/formats/imports/election/internal_proporz.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.formats.imports.common import EXPATS from onegov.election_day.formats.imports.common import FileImportError @@ -60,7 +62,7 @@ ) -def parse_election(line: 'DefaultRow', errors: list[str]) -> 'Status | None': +def parse_election(line: DefaultRow, errors: list[str]) -> Status | None: status = None try: status = line.election_status or 'unknown' @@ -72,11 +74,11 @@ def parse_election(line: 'DefaultRow', errors: list[str]) -> 'Status | None': def parse_election_result( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], entities: dict[int, dict[str, str]], - election: 'Election', - principal: 'Canton | Municipality', + election: Election, + principal: Canton | Municipality, ignore_extra: bool ) -> dict[str, Any] | bool: @@ -137,7 +139,7 @@ def parse_election_result( def parse_list( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], election_id: str, colors: dict[str, str] @@ -164,7 +166,7 @@ def parse_list( def parse_list_result( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], counted: bool ) -> dict[str, Any] | None: @@ -181,7 +183,7 @@ def parse_list_result( return None -def parse_list_panachage_headers(csv: 'DefaultCSVFile') -> dict[str, str]: +def parse_list_panachage_headers(csv: DefaultCSVFile) -> dict[str, str]: headers = {} prefix = 'list_panachage_votes_from_list_' for header in csv.headers: @@ -200,7 +202,7 @@ def parse_list_panachage_headers(csv: 'DefaultCSVFile') -> dict[str, str]: def parse_list_panachage_results( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], values: dict[str, dict[str, int]], headers: dict[str, str] @@ -225,7 +227,7 @@ def parse_list_panachage_results( def parse_candidate( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], election_id: str, colors: dict[str, str] @@ -265,7 +267,7 @@ def parse_candidate( def parse_candidate_result( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], counted: bool ) -> dict[str, Any] | None: @@ -282,7 +284,7 @@ def parse_candidate_result( return None -def parse_candidate_panachage_headers(csv: 'DefaultCSVFile') -> dict[str, str]: +def parse_candidate_panachage_headers(csv: DefaultCSVFile) -> dict[str, str]: headers = {} prefix = 'candidate_panachage_votes_from_list_' for header in csv.headers: @@ -299,7 +301,7 @@ def parse_candidate_panachage_headers(csv: 'DefaultCSVFile') -> dict[str, str]: def parse_candidate_panachage_results( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], values: list[dict[str, Any]], headers: dict[str, str] @@ -332,7 +334,7 @@ def prefix_connection_id(connection_id: str, parent_connection_id: str) -> str: def parse_connection( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], election_id: str ) -> tuple[dict[str, Any] | None, dict[str, Any] | None]: @@ -364,8 +366,8 @@ def parse_connection( def import_election_internal_proporz( - election: 'Election', - principal: 'Canton | Municipality', + election: Election, + principal: Canton | Municipality, file: IO[bytes], mimetype: str, ignore_extra: bool = False diff --git a/src/onegov/election_day/formats/imports/election/wabstic_majorz.py b/src/onegov/election_day/formats/imports/election/wabstic_majorz.py index acc23039ce..2b5e9941cc 100644 --- a/src/onegov/election_day/formats/imports/election/wabstic_majorz.py +++ b/src/onegov/election_day/formats/imports/election/wabstic_majorz.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.formats.imports.common import EXPATS from onegov.election_day.formats.imports.common import FileImportError @@ -63,15 +65,15 @@ ) -def get_entity_id(line: 'DefaultRow') -> int: +def get_entity_id(line: DefaultRow) -> int: col = 'bfsnrgemeinde' entity_id = validate_integer(line, col) return 0 if entity_id in EXPATS else entity_id def import_election_wabstic_majorz( - election: 'Election', - principal: 'Canton | Municipality', + election: Election, + principal: Canton | Municipality, number: str, district: str, file_wm_wahl: IO[bytes], diff --git a/src/onegov/election_day/formats/imports/election/wabstic_proporz.py b/src/onegov/election_day/formats/imports/election/wabstic_proporz.py index d005265b30..a56b068971 100644 --- a/src/onegov/election_day/formats/imports/election/wabstic_proporz.py +++ b/src/onegov/election_day/formats/imports/election/wabstic_proporz.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.formats.imports.common import EXPATS from onegov.election_day.formats.imports.common import FileImportError @@ -83,13 +85,13 @@ ) -def get_entity_id(line: 'DefaultRow', expats: 'Collection[int]') -> int: +def get_entity_id(line: DefaultRow, expats: Collection[int]) -> int: col = 'bfsnrgemeinde' entity_id = validate_integer(line, col) return 0 if entity_id in expats else entity_id -def get_list_id_from_knr(line: 'DefaultRow') -> str: +def get_list_id_from_knr(line: DefaultRow) -> str: """ Takes a line from csv file with a candidate number (knr) in it and returns the derived listnr for this candidate. Will also handle the new @@ -100,7 +102,7 @@ def get_list_id_from_knr(line: 'DefaultRow') -> str: return line.knr[0:-2] -def get_list_id(line: 'DefaultRow') -> str: +def get_list_id(line: DefaultRow) -> str: number = line.listnr or '0' # wabstiC 99 is blank list that maps to 999 see open_data_de.md number = '999' if number == '99' else number @@ -109,7 +111,7 @@ def get_list_id(line: 'DefaultRow') -> str: def import_election_wabstic_proporz( election: ProporzElection, - principal: 'Canton | Municipality', + principal: Canton | Municipality, number: str, district: str | None = None, file_wp_wahl: IO[bytes] | None = None, diff --git a/src/onegov/election_day/formats/imports/election_compound/__init__.py b/src/onegov/election_day/formats/imports/election_compound/__init__.py index 173c1f620d..a9f6a951fe 100644 --- a/src/onegov/election_day/formats/imports/election_compound/__init__.py +++ b/src/onegov/election_day/formats/imports/election_compound/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.imports.election_compound.internal import ( import_election_compound_internal) diff --git a/src/onegov/election_day/formats/imports/election_compound/internal.py b/src/onegov/election_day/formats/imports/election_compound/internal.py index 140c29e6cb..adf1939d41 100644 --- a/src/onegov/election_day/formats/imports/election_compound/internal.py +++ b/src/onegov/election_day/formats/imports/election_compound/internal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.imports.election.internal_proporz import ( import_election_internal_proporz) from onegov.election_day import _ @@ -13,8 +15,8 @@ def import_election_compound_internal( - compound: 'ElectionCompound', - principal: 'Canton | Municipality', + compound: ElectionCompound, + principal: Canton | Municipality, file: IO[bytes], mimetype: str ) -> list[FileImportError]: diff --git a/src/onegov/election_day/formats/imports/party_result/__init__.py b/src/onegov/election_day/formats/imports/party_result/__init__.py index ca5b92b443..6b3188c863 100644 --- a/src/onegov/election_day/formats/imports/party_result/__init__.py +++ b/src/onegov/election_day/formats/imports/party_result/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.imports.party_result.internal import ( import_party_results_internal) diff --git a/src/onegov/election_day/formats/imports/party_result/internal.py b/src/onegov/election_day/formats/imports/party_result/internal.py index cc9f3e990b..5587fc9854 100644 --- a/src/onegov/election_day/formats/imports/party_result/internal.py +++ b/src/onegov/election_day/formats/imports/party_result/internal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.formats.imports.common import FileImportError from onegov.election_day.formats.imports.common import load_csv @@ -36,10 +38,10 @@ def parse_domain( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], - election: 'ProporzElection | ElectionCompound', - principal: 'Canton | Municipality', + election: ProporzElection | ElectionCompound, + principal: Canton | Municipality, election_year: int ) -> tuple[bool, str | None, str | None]: """ Parse domain and domain segment. Also indicate, if line should be @@ -81,13 +83,13 @@ def parse_domain( def parse_party_result( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], party_results: dict[str, PartyResult], totals: dict[int, dict[tuple[str | None, str | None], int | None]], parties: set[str], election_year: int, - locales: 'Collection[str]', + locales: Collection[str], default_locale: str, colors: dict[str, str], domain: str | None, @@ -164,7 +166,7 @@ def parse_party_result( colors[name] = color -def parse_panachage_headers(csv: 'DefaultCSVFile') -> dict[str, str]: +def parse_panachage_headers(csv: DefaultCSVFile) -> dict[str, str]: headers = {} for header in csv.headers: if not header.startswith('panachage_votes_from_'): @@ -176,7 +178,7 @@ def parse_panachage_headers(csv: 'DefaultCSVFile') -> dict[str, str]: def parse_panachage_results( - line: 'DefaultRow', + line: DefaultRow, errors: list[str], results: dict[str, dict[str, int]], headers: dict[str, str], @@ -198,11 +200,11 @@ def parse_panachage_results( def import_party_results_internal( - election: 'ProporzElection | ElectionCompound', - principal: 'Canton | Municipality', + election: ProporzElection | ElectionCompound, + principal: Canton | Municipality, file: IO[bytes], mimetype: str, - locales: 'Collection[str]', + locales: Collection[str], default_locale: str ) -> list[FileImportError]: """ Tries to import the given file. diff --git a/src/onegov/election_day/formats/imports/vote/__init__.py b/src/onegov/election_day/formats/imports/vote/__init__.py index a3f2e53a5a..09e04a98c6 100644 --- a/src/onegov/election_day/formats/imports/vote/__init__.py +++ b/src/onegov/election_day/formats/imports/vote/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.formats.imports.vote.ech import ( import_votes_ech) from onegov.election_day.formats.imports.vote.internal import ( diff --git a/src/onegov/election_day/formats/imports/vote/ech.py b/src/onegov/election_day/formats/imports/vote/ech.py index 2cbaa8db87..b6da33d48d 100644 --- a/src/onegov/election_day/formats/imports/vote/ech.py +++ b/src/onegov/election_day/formats/imports/vote/ech.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.formats.imports.common import convert_ech_domain from onegov.election_day.formats.imports.common import EXPATS @@ -24,10 +26,10 @@ def import_votes_ech( - principal: 'Canton | Municipality', - delivery: 'DeliveryV1 | DeliveryV2', - session: 'Session' -) -> 'ECHImportResultType': + principal: Canton | Municipality, + delivery: DeliveryV1 | DeliveryV2, + session: Session +) -> ECHImportResultType: """ Imports all votes in a given eCH-0252 delivery. Deletes votes on the same day not appearing in the delivery. diff --git a/src/onegov/election_day/formats/imports/vote/internal.py b/src/onegov/election_day/formats/imports/vote/internal.py index a4866aeea9..15553f687b 100644 --- a/src/onegov/election_day/formats/imports/vote/internal.py +++ b/src/onegov/election_day/formats/imports/vote/internal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.formats.imports.common import BALLOT_TYPES from onegov.election_day.formats.imports.common import EXPATS @@ -38,8 +40,8 @@ def import_vote_internal( - vote: 'Vote', - principal: 'Canton | Municipality', + vote: Vote, + principal: Canton | Municipality, file: IO[bytes], mimetype: str ) -> list[FileImportError]: diff --git a/src/onegov/election_day/formats/imports/vote/wabstic.py b/src/onegov/election_day/formats/imports/vote/wabstic.py index b07a8791bb..bc4edd51fe 100644 --- a/src/onegov/election_day/formats/imports/vote/wabstic.py +++ b/src/onegov/election_day/formats/imports/vote/wabstic.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.formats.imports.common import EXPATS from onegov.election_day.formats.imports.common import FileImportError @@ -62,7 +64,7 @@ def parse_domain(domain: str) -> str | None: def line_is_relevant( - line: 'DefaultRow', + line: DefaultRow, domain: str, district: str, number: str @@ -75,8 +77,8 @@ def line_is_relevant( def import_vote_wabstic( - vote: 'Vote', - principal: 'Canton | Municipality', + vote: Vote, + principal: Canton | Municipality, number: str, district: str, file_sg_geschaefte: IO[bytes], diff --git a/src/onegov/election_day/forms/__init__.py b/src/onegov/election_day/forms/__init__.py index 51c5644180..17d20126ef 100644 --- a/src/onegov/election_day/forms/__init__.py +++ b/src/onegov/election_day/forms/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.forms.archive import ArchiveSearchFormElection from onegov.election_day.forms.archive import ArchiveSearchFormVote from onegov.election_day.forms.common import ClearResultsForm diff --git a/src/onegov/election_day/forms/archive.py b/src/onegov/election_day/forms/archive.py index 720f0c2f83..23f3a01609 100644 --- a/src/onegov/election_day/forms/archive.py +++ b/src/onegov/election_day/forms/archive.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.form import Form from onegov.form.fields import MultiCheckboxField @@ -14,7 +16,7 @@ class ArchiveSearchForm(Form): - request: 'ElectionDayRequest' + request: ElectionDayRequest term = StringField( label=_('Term'), @@ -51,7 +53,7 @@ def select_all(self, name: str) -> None: if not field.data: field.data = list(next(zip(*field.choices))) - def apply_model(self, model: 'SearchableArchivedResultCollection') -> None: + def apply_model(self, model: SearchableArchivedResultCollection) -> None: self.term.data = model.term self.from_date.data = model.from_date self.to_date.data = model.to_date @@ -77,7 +79,7 @@ def on_request(self) -> None: principal = self.request.app.principal self.domains.choices = list(principal.domains_vote.items()) - def apply_model(self, model: 'SearchableArchivedResultCollection') -> None: + def apply_model(self, model: SearchableArchivedResultCollection) -> None: super().apply_model(model) self.answers.data = model.answers self.select_all('answers') diff --git a/src/onegov/election_day/forms/common.py b/src/onegov/election_day/forms/common.py index df816a1a9a..0226a18a0f 100644 --- a/src/onegov/election_day/forms/common.py +++ b/src/onegov/election_day/forms/common.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.form import Form from wtforms.fields import BooleanField diff --git a/src/onegov/election_day/forms/data_source.py b/src/onegov/election_day/forms/data_source.py index 5bdefb8613..67263ea3c2 100644 --- a/src/onegov/election_day/forms/data_source.py +++ b/src/onegov/election_day/forms/data_source.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.layouts import DefaultLayout from onegov.election_day.models.data_source import UPLOAD_TYPE_LABELS @@ -33,20 +35,20 @@ class DataSourceForm(Form): default='vote' ) - def update_model(self, model: 'DataSource') -> None: + def update_model(self, model: DataSource) -> None: assert self.name.data is not None assert self.upload_type.data is not None model.name = self.name.data model.type = self.upload_type.data - def apply_model(self, model: 'DataSource') -> None: + def apply_model(self, model: DataSource) -> None: self.name.data = model.name self.upload_type.data = model.type class DataSourceItemForm(Form): - request: 'ElectionDayRequest' + request: ElectionDayRequest item = ChosenSelectField( label='', @@ -71,7 +73,7 @@ class DataSourceItemForm(Form): callout = '' - def populate(self, source: 'DataSource') -> None: + def populate(self, source: DataSource) -> None: layout = DefaultLayout(None, self.request) self.type = source.type @@ -93,7 +95,7 @@ def populate(self, source: 'DataSource') -> None: else: self.callout = _('No elections yet.') - def update_model(self, model: 'DataSourceItem') -> None: + def update_model(self, model: DataSourceItem) -> None: if self.type == 'vote': model.vote_id = self.item.data else: @@ -102,7 +104,7 @@ def update_model(self, model: 'DataSourceItem') -> None: model.district = self.district.data model.number = self.number.data - def apply_model(self, model: 'DataSourceItem') -> None: + def apply_model(self, model: DataSourceItem) -> None: if self.type == 'vote': self.item.data = model.vote_id else: diff --git a/src/onegov/election_day/forms/election.py b/src/onegov/election_day/forms/election.py index 673e30cb20..2c720e4933 100644 --- a/src/onegov/election_day/forms/election.py +++ b/src/onegov/election_day/forms/election.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from onegov.core.utils import Bunch from onegov.core.utils import normalize_for_url @@ -37,7 +39,7 @@ class ElectionForm(Form): - request: 'ElectionDayRequest' + request: ElectionDayRequest id_hint = PanelField( label=_('Identifier'), diff --git a/src/onegov/election_day/forms/election_compound.py b/src/onegov/election_day/forms/election_compound.py index ff3a117b02..61be3c5e4c 100644 --- a/src/onegov/election_day/forms/election_compound.py +++ b/src/onegov/election_day/forms/election_compound.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from onegov.core.utils import Bunch from onegov.core.utils import normalize_for_url @@ -35,7 +37,7 @@ class ElectionCompoundForm(Form): - request: 'ElectionDayRequest' + request: ElectionDayRequest id_hint = PanelField( label=_('Identifier'), diff --git a/src/onegov/election_day/forms/notification.py b/src/onegov/election_day/forms/notification.py index 7e97119655..2bbd5dfd47 100644 --- a/src/onegov/election_day/forms/notification.py +++ b/src/onegov/election_day/forms/notification.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.models import Election from onegov.election_day.models import ElectionCompound @@ -17,7 +19,7 @@ class TriggerNotificationForm(Form): - request: 'ElectionDayRequest' + request: ElectionDayRequest notifications = MultiCheckboxField( label=_('Notifications'), @@ -73,7 +75,7 @@ def ensure_items_selected(self) -> bool: return False return True - def latest_date(self, session: 'Session') -> 'date | None': + def latest_date(self, session: Session) -> date | None: query = session.query(Election.date) row = query.order_by(Election.date.desc()).first() latest_election = row[0] if row else None @@ -86,7 +88,7 @@ def latest_date(self, session: 'Session') -> 'date | None': return max((latest_election, latest_vote)) return latest_election or latest_vote - def available_elections(self, session: 'Session') -> 'Query[Election]': + def available_elections(self, session: Session) -> Query[Election]: query = session.query(Election) query = query.order_by(Election.shortcode) query = query.filter(Election.date == self.latest_date(session)) @@ -94,8 +96,8 @@ def available_elections(self, session: 'Session') -> 'Query[Election]': def available_election_compounds( self, - session: 'Session' - ) -> 'Query[ElectionCompound]': + session: Session + ) -> Query[ElectionCompound]: query = session.query(ElectionCompound) query = query.order_by(ElectionCompound.shortcode) @@ -104,13 +106,13 @@ def available_election_compounds( ) return query - def available_votes(self, session: 'Session') -> 'Query[Vote]': + def available_votes(self, session: Session) -> Query[Vote]: query = session.query(Vote) query = query.order_by(Vote.shortcode) query = query.filter(Vote.date == self.latest_date(session)) return query - def election_models(self, session: 'Session') -> list[Election]: + def election_models(self, session: Session) -> list[Election]: if not self.elections.data: return [] @@ -121,7 +123,7 @@ def election_models(self, session: 'Session') -> list[Election]: def election_compound_models( self, - session: 'Session' + session: Session ) -> list[ElectionCompound]: if not self.election_compounds.data: @@ -134,7 +136,7 @@ def election_compound_models( query = query.order_by(ElectionCompound.shortcode) return query.all() - def vote_models(self, session: 'Session') -> list[Vote]: + def vote_models(self, session: Session) -> list[Vote]: if not self.votes.data: return [] diff --git a/src/onegov/election_day/forms/screen.py b/src/onegov/election_day/forms/screen.py index ed7326b0f1..3dc630ad8f 100644 --- a/src/onegov/election_day/forms/screen.py +++ b/src/onegov/election_day/forms/screen.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from lxml.etree import XMLSyntaxError from onegov.core.widgets import transform_structure from onegov.election_day import _ @@ -211,7 +213,7 @@ class ScreenForm(Form): render_kw={'rows': 10}, ) - def get_widgets(self, type_: str) -> dict[str, 'ScreenWidget']: + def get_widgets(self, type_: str) -> dict[str, ScreenWidget]: registry = self.request.app.config.screen_widget_registry return registry.by_categories(ScreenType(type_).categories) diff --git a/src/onegov/election_day/forms/subscription.py b/src/onegov/election_day/forms/subscription.py index 6ab76d8282..c2c37985c1 100644 --- a/src/onegov/election_day/forms/subscription.py +++ b/src/onegov/election_day/forms/subscription.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from onegov.election_day import _ from onegov.election_day.forms.upload.common import ALLOWED_MIME_TYPES @@ -23,7 +25,7 @@ class SubscriptionForm(Form): - request: 'ElectionDayRequest' + request: ElectionDayRequest domain = RadioField( label=_('Type'), diff --git a/src/onegov/election_day/forms/upload/__init__.py b/src/onegov/election_day/forms/upload/__init__.py index 9bb7be8127..ed2e126d0f 100644 --- a/src/onegov/election_day/forms/upload/__init__.py +++ b/src/onegov/election_day/forms/upload/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.forms.upload.election_compound import ( UploadElectionCompoundForm) from onegov.election_day.forms.upload.election import UploadMajorzElectionForm diff --git a/src/onegov/election_day/forms/upload/common.py b/src/onegov/election_day/forms/upload/common.py index 97e274dd05..e50464640e 100644 --- a/src/onegov/election_day/forms/upload/common.py +++ b/src/onegov/election_day/forms/upload/common.py @@ -1,3 +1,4 @@ +from __future__ import annotations ALLOWED_MIME_TYPES = { 'application/excel', diff --git a/src/onegov/election_day/forms/upload/election.py b/src/onegov/election_day/forms/upload/election.py index e9e12f166f..21854e4248 100644 --- a/src/onegov/election_day/forms/upload/election.py +++ b/src/onegov/election_day/forms/upload/election.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.forms.upload.common import ALLOWED_MIME_TYPES from onegov.election_day.forms.upload.common import MAX_FILE_SIZE @@ -43,8 +45,8 @@ class UploadElectionBaseForm(Form): def adjust( self, - principal: 'Canton | Municipality', - election: 'Election' + principal: Canton | Municipality, + election: Election ) -> None: """ Adjusts the form to the given principal and election. """ diff --git a/src/onegov/election_day/forms/upload/election_compound.py b/src/onegov/election_day/forms/upload/election_compound.py index 9b4c2592df..e2b63c34c3 100644 --- a/src/onegov/election_day/forms/upload/election_compound.py +++ b/src/onegov/election_day/forms/upload/election_compound.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.forms.upload.common import ALLOWED_MIME_TYPES from onegov.election_day.forms.upload.common import MAX_FILE_SIZE diff --git a/src/onegov/election_day/forms/upload/party_results.py b/src/onegov/election_day/forms/upload/party_results.py index c6e24bd29d..49658f4677 100644 --- a/src/onegov/election_day/forms/upload/party_results.py +++ b/src/onegov/election_day/forms/upload/party_results.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.forms.upload.common import ALLOWED_MIME_TYPES from onegov.election_day.forms.upload.common import MAX_FILE_SIZE diff --git a/src/onegov/election_day/forms/upload/rest.py b/src/onegov/election_day/forms/upload/rest.py index c7e6bf89f1..2da592d171 100644 --- a/src/onegov/election_day/forms/upload/rest.py +++ b/src/onegov/election_day/forms/upload/rest.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.forms.upload.common import ALLOWED_MIME_TYPES from onegov.election_day.forms.upload.common import ALLOWED_MIME_TYPES_XML diff --git a/src/onegov/election_day/forms/upload/vote.py b/src/onegov/election_day/forms/upload/vote.py index 7e4d5c6a0a..cc094e67a8 100644 --- a/src/onegov/election_day/forms/upload/vote.py +++ b/src/onegov/election_day/forms/upload/vote.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.forms.upload.common import ALLOWED_MIME_TYPES from onegov.election_day.forms.upload.common import MAX_FILE_SIZE @@ -61,7 +63,7 @@ class UploadVoteForm(Form): render_kw={'force_simple': True} ) - def adjust(self, principal: 'Canton | Municipality', vote: 'Vote') -> None: + def adjust(self, principal: Canton | Municipality, vote: Vote) -> None: """ Adjusts the form to the given principal and vote. """ assert hasattr(vote, 'data_sources') diff --git a/src/onegov/election_day/forms/upload/wabsti_majorz.py b/src/onegov/election_day/forms/upload/wabsti_majorz.py index f618098423..5ed73d6135 100644 --- a/src/onegov/election_day/forms/upload/wabsti_majorz.py +++ b/src/onegov/election_day/forms/upload/wabsti_majorz.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.forms.upload.common import ALLOWED_MIME_TYPES from onegov.election_day.forms.upload.common import MAX_FILE_SIZE from onegov.form import Form diff --git a/src/onegov/election_day/forms/upload/wabsti_proporz.py b/src/onegov/election_day/forms/upload/wabsti_proporz.py index 07ecd1f275..6b5e610b3c 100644 --- a/src/onegov/election_day/forms/upload/wabsti_proporz.py +++ b/src/onegov/election_day/forms/upload/wabsti_proporz.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.forms.upload.common import ALLOWED_MIME_TYPES from onegov.election_day.forms.upload.common import MAX_FILE_SIZE from onegov.form import Form diff --git a/src/onegov/election_day/forms/upload/wabsti_vote.py b/src/onegov/election_day/forms/upload/wabsti_vote.py index 878c00aafc..3e191b0a66 100644 --- a/src/onegov/election_day/forms/upload/wabsti_vote.py +++ b/src/onegov/election_day/forms/upload/wabsti_vote.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.forms.upload.common import ALLOWED_MIME_TYPES from onegov.election_day.forms.upload.common import MAX_FILE_SIZE from onegov.form import Form diff --git a/src/onegov/election_day/forms/vote.py b/src/onegov/election_day/forms/vote.py index 7af2069155..1719e07baa 100644 --- a/src/onegov/election_day/forms/vote.py +++ b/src/onegov/election_day/forms/vote.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from onegov.core.utils import normalize_for_url from onegov.election_day import _ @@ -29,7 +31,7 @@ class VoteForm(Form): - request: 'ElectionDayRequest' + request: ElectionDayRequest id_hint = PanelField( label=_('Identifier'), diff --git a/src/onegov/election_day/hidden_by_principal.py b/src/onegov/election_day/hidden_by_principal.py index 943b424346..913e724692 100644 --- a/src/onegov/election_day/hidden_by_principal.py +++ b/src/onegov/election_day/hidden_by_principal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import TYPE_CHECKING if TYPE_CHECKING: from onegov.election_day.models import Election @@ -12,8 +14,8 @@ def hide_candidates_chart( - election: 'Election', - request: 'ElectionDayRequest', + election: Election, + request: ElectionDayRequest, default: bool = hide_candidates_chart_intermediate_results ) -> bool: return request.app.principal.hidden_elements.get( @@ -23,8 +25,8 @@ def hide_candidates_chart( def hide_connections_chart( - election: 'Election', - request: 'ElectionDayRequest', + election: Election, + request: ElectionDayRequest, default: bool = hide_connections_chart_intermediate_results ) -> bool: return request.app.principal.hidden_elements.get( @@ -34,7 +36,7 @@ def hide_connections_chart( def hide_candidate_entity_map_percentages( - request: 'ElectionDayRequest', + request: ElectionDayRequest, default: bool = always_hide_candidate_by_entity_chart_percentages ) -> bool: return request.app.principal.hidden_elements.get( @@ -44,7 +46,7 @@ def hide_candidate_entity_map_percentages( def hide_candidate_district_map_percentages( - request: 'ElectionDayRequest', + request: ElectionDayRequest, default: bool = always_hide_candidate_by_district_chart_percentages ) -> bool: return request.app.principal.hidden_elements.get( diff --git a/src/onegov/election_day/i18n.py b/src/onegov/election_day/i18n.py index f7af9796ce..33d30dcea3 100644 --- a/src/onegov/election_day/i18n.py +++ b/src/onegov/election_day/i18n.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.i18n.translation_string import TranslationStringFactory _ = TranslationStringFactory('onegov.election_day') diff --git a/src/onegov/election_day/layouts/__init__.py b/src/onegov/election_day/layouts/__init__.py index db669bed97..3da7b3bacd 100644 --- a/src/onegov/election_day/layouts/__init__.py +++ b/src/onegov/election_day/layouts/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.layouts.default import DefaultLayout from onegov.election_day.layouts.election import ElectionLayout from onegov.election_day.layouts.election_compound import ( diff --git a/src/onegov/election_day/layouts/archive.py b/src/onegov/election_day/layouts/archive.py index ba2c5fcef6..668fdc8c11 100644 --- a/src/onegov/election_day/layouts/archive.py +++ b/src/onegov/election_day/layouts/archive.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.election_day import _ from onegov.election_day.collections import SearchableArchivedResultCollection @@ -16,7 +18,7 @@ class ArchiveLayout(DefaultLayout): def __init__( self, model: SearchableArchivedResultCollection, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: super().__init__(model, request) diff --git a/src/onegov/election_day/layouts/default.py b/src/onegov/election_day/layouts/default.py index aaa2fa576b..dfb075c8ca 100644 --- a/src/onegov/election_day/layouts/default.py +++ b/src/onegov/election_day/layouts/default.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from babel import Locale from fs.errors import ResourceNotFound from functools import cached_property @@ -36,10 +38,10 @@ class DefaultLayout(ChameleonLayout): docs_base_url = ('https://github.com/OneGov/onegov-cloud/blob/master/src' '/onegov/election_day/static/docs/api') - app: 'ElectionDayApp' - request: 'ElectionDayRequest' + app: ElectionDayApp + request: ElectionDayRequest - def __init__(self, model: Any, request: 'ElectionDayRequest') -> None: + def __init__(self, model: Any, request: ElectionDayRequest) -> None: super().__init__(model, request) self.request.include('common') @@ -56,7 +58,7 @@ def title(self) -> str: return '' @cached_property - def principal(self) -> 'Canton | Municipality': + def principal(self) -> Canton | Municipality: return self.request.app.principal def label(self, value: str) -> str: @@ -181,7 +183,7 @@ def get_link(locale: str) -> str: for locale in sorted(self.app.locales) ] - def format_name(self, item: 'HasName') -> str: + def format_name(self, item: HasName) -> str: if hasattr(item, 'entity_id'): return item.name if item.entity_id else _('Expats') return item.name or _('Expats') @@ -200,7 +202,7 @@ def archive_download(self) -> str: return self.request.link(self.principal, name='archive-download') @property - def last_archive_modification(self) -> 'datetime | None': + def last_archive_modification(self) -> datetime | None: try: filestorage = self.request.app.filestorage assert filestorage is not None diff --git a/src/onegov/election_day/layouts/detail.py b/src/onegov/election_day/layouts/detail.py index 3e11e328a7..9696a48864 100644 --- a/src/onegov/election_day/layouts/detail.py +++ b/src/onegov/election_day/layouts/detail.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.election_day.layouts.default import DefaultLayout @@ -20,8 +22,8 @@ class DetailLayout(DefaultLayout): """ - model: 'Election | ElectionCompound | ElectionCompoundPart | Vote' - request: 'ElectionDayRequest' + model: Election | ElectionCompound | ElectionCompoundPart | Vote + request: ElectionDayRequest @cached_property def has_results(self) -> bool: @@ -32,11 +34,11 @@ def completed(self) -> bool: return self.model.completed @cached_property - def last_result_change(self) -> 'datetime | None': + def last_result_change(self) -> datetime | None: return self.model.last_result_change @cached_property - def last_modified(self) -> 'datetime | None': + def last_modified(self) -> datetime | None: return self.model.last_modified @cached_property @@ -53,7 +55,7 @@ def related_link_label(self) -> str | None: return link_labels.get(locale, None) @cached_property - def explanations_pdf(self) -> 'File | None': + def explanations_pdf(self) -> File | None: return getattr(self.model, 'explanations_pdf', None) @cached_property diff --git a/src/onegov/election_day/layouts/election.py b/src/onegov/election_day/layouts/election.py index 6228291dfa..734318adae 100644 --- a/src/onegov/election_day/layouts/election.py +++ b/src/onegov/election_day/layouts/election.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.utils import normalize_for_url from onegov.election_day import _ @@ -24,12 +26,12 @@ class ElectionLayout(DetailLayout): - model: 'Election' + model: Election def __init__( self, - model: 'Election', - request: 'ElectionDayRequest', + model: Election, + request: ElectionDayRequest, tab: str | None = None ) -> None: super().__init__(model, request) @@ -244,7 +246,7 @@ def main_view(self) -> str: return self.request.link(self.model, 'lists') @cached_property - def menu(self) -> 'NestedMenu': + def menu(self) -> NestedMenu: result: NestedMenu = [] submenus = ( @@ -352,5 +354,5 @@ def related_elections(self) -> list[tuple[str | None, str]]: return [(e.title, self.request.link(e)) for e in result] @cached_property - def results(self) -> 'list[ElectionResult]': + def results(self) -> list[ElectionResult]: return self.model.results diff --git a/src/onegov/election_day/layouts/election_compound.py b/src/onegov/election_day/layouts/election_compound.py index 3e68e63905..37d6d60747 100644 --- a/src/onegov/election_day/layouts/election_compound.py +++ b/src/onegov/election_day/layouts/election_compound.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.utils import normalize_for_url from onegov.election_day import _ @@ -18,12 +20,12 @@ class ElectionCompoundLayout(DetailLayout): - model: 'ElectionCompound' + model: ElectionCompound def __init__( self, - model: 'ElectionCompound', - request: 'ElectionDayRequest', + model: ElectionCompound, + request: ElectionDayRequest, tab: str | None = None ) -> None: super().__init__(model, request) @@ -78,11 +80,11 @@ def all_tabs(self) -> tuple[str, ...]: return tuple(result) @cached_property - def results(self) -> list['ResultRow']: + def results(self) -> list[ResultRow]: return self.model.results @cached_property - def totals(self) -> 'TotalRow': + def totals(self) -> TotalRow: return self.model.totals @cached_property @@ -187,7 +189,7 @@ def main_view(self) -> str: return self.request.link(self.model, 'districts') @cached_property - def menu(self) -> 'NestedMenu': + def menu(self) -> NestedMenu: return [ ( self.title(tab), diff --git a/src/onegov/election_day/layouts/election_compound_part.py b/src/onegov/election_day/layouts/election_compound_part.py index 15b4775c0b..3625a17ff8 100644 --- a/src/onegov/election_day/layouts/election_compound_part.py +++ b/src/onegov/election_day/layouts/election_compound_part.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.utils import normalize_for_url from onegov.election_day import _ @@ -17,12 +19,12 @@ class ElectionCompoundPartLayout(DetailLayout): - model: 'ElectionCompoundPart' + model: ElectionCompoundPart def __init__( self, - model: 'ElectionCompoundPart', - request: 'ElectionDayRequest', + model: ElectionCompoundPart, + request: ElectionDayRequest, tab: str | None = None ) -> None: super().__init__(model, request) @@ -69,11 +71,11 @@ def all_tabs(self) -> tuple[str, ...]: return tuple(result) @cached_property - def results(self) -> list['ResultRow']: + def results(self) -> list[ResultRow]: return self.model.results @cached_property - def totals(self) -> 'TotalRow': + def totals(self) -> TotalRow: return self.model.totals def label(self, value: str) -> str: @@ -130,7 +132,7 @@ def main_view(self) -> str: return self.request.link(self.model, 'districts') @cached_property - def menu(self) -> 'NestedMenu': + def menu(self) -> NestedMenu: return [ ( self.title(tab), diff --git a/src/onegov/election_day/layouts/mail.py b/src/onegov/election_day/layouts/mail.py index c2191b8240..5584cbe821 100644 --- a/src/onegov/election_day/layouts/mail.py +++ b/src/onegov/election_day/layouts/mail.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.i18n import SiteLocale from onegov.election_day import _ @@ -16,7 +18,7 @@ class MailLayout(DefaultLayout): """ A special layout for creating HTML E-Mails. """ @cached_property - def base(self) -> 'PageTemplateFile': + def base(self) -> PageTemplateFile: return self.template_loader['mail_layout.pt'] @cached_property @@ -25,7 +27,7 @@ def primary_color(self) -> str: def model_title( self, - model: 'Election | ElectionCompound | Vote' + model: Election | ElectionCompound | Vote ) -> str | None: """ Returns the translated title of the given election or vote. Falls back to the title of the default fallback, if no translated title is @@ -45,7 +47,7 @@ def model_url(self, model: object) -> str: self.request, self.request.link(model) ) - def subject(self, model: 'Election | ElectionCompound | Vote') -> str: + def subject(self, model: Election | ElectionCompound | Vote) -> str: """ Returns a nice subject for the given model. """ result = _('New intermediate results') diff --git a/src/onegov/election_day/layouts/manage.py b/src/onegov/election_day/layouts/manage.py index ebc95fb5e5..d7703f12db 100644 --- a/src/onegov/election_day/layouts/manage.py +++ b/src/onegov/election_day/layouts/manage.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.election_day import _ from onegov.election_day.collections import DataSourceCollection @@ -38,7 +40,7 @@ class ManageLayout(DefaultLayout): - def __init__(self, model: Any, request: 'ElectionDayRequest'): + def __init__(self, model: Any, request: ElectionDayRequest): super().__init__(model, request) self.request.include('backend_common') self.request.include('chosen') @@ -51,7 +53,7 @@ def manage_model_link(self) -> str: return self.request.link(self.model) @cached_property - def menu(self) -> 'NestedMenu': + def menu(self) -> NestedMenu: session = self.request.session principal = self.principal @@ -196,7 +198,7 @@ def title(self) -> str: def clear_media( self, - tabs: 'Collection[str] | None' = None, + tabs: Collection[str] | None = None, additional: list[str] | None = None ) -> int: @@ -230,7 +232,7 @@ class ManageElectionsLayout(ManageLayout): def __init__( self, model: Election | ElectionCollection, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: super().__init__(model, request) @@ -258,7 +260,7 @@ class ManageElectionCompoundsLayout(ManageLayout): def __init__( self, model: ElectionCompound | ElectionCompoundCollection, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: super().__init__(model, request) @@ -286,7 +288,7 @@ class ManageVotesLayout(ManageLayout): def __init__( self, model: Vote | VoteCollection, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: super().__init__(model, request) @@ -318,12 +320,12 @@ def clear_media(self) -> int: # type:ignore[override] class ManageSubscribersLayout(ManageLayout): - model: 'SubscriberCollection[Any] | Subscriber' + model: SubscriberCollection[Any] | Subscriber def __init__( self, - model: 'SubscriberCollection[Any] | Subscriber', - request: 'ElectionDayRequest' + model: SubscriberCollection[Any] | Subscriber, + request: ElectionDayRequest ) -> None: super().__init__(model, request) @@ -359,12 +361,12 @@ def manage_model_link(self) -> str: class ManageUploadTokensLayout(ManageLayout): - model: 'UploadToken | UploadTokenCollection' + model: UploadToken | UploadTokenCollection def __init__( self, - model: 'UploadToken | UploadTokenCollection', - request: 'ElectionDayRequest' + model: UploadToken | UploadTokenCollection, + request: ElectionDayRequest ) -> None: super().__init__(model, request) @@ -381,7 +383,7 @@ def manage_model_link(self) -> str: class ManageDataSourcesLayout(ManageLayout): - def __init__(self, model: Any, request: 'ElectionDayRequest') -> None: + def __init__(self, model: Any, request: ElectionDayRequest) -> None: super().__init__(model, request) self.breadcrumbs.append( @@ -397,12 +399,12 @@ def manage_model_link(self) -> str: class ManageDataSourceItemsLayout(ManageLayout): - model: 'DataSource | DataSourceItemCollection' + model: DataSource | DataSourceItemCollection def __init__( self, - model: 'DataSource | DataSourceItemCollection', - request: 'ElectionDayRequest' + model: DataSource | DataSourceItemCollection, + request: ElectionDayRequest ) -> None: super().__init__(model, request) @@ -431,7 +433,7 @@ def manage_model_link(self) -> str: class ManageScreensLayout(ManageLayout): - def __init__(self, model: Any, request: 'ElectionDayRequest') -> None: + def __init__(self, model: Any, request: ElectionDayRequest) -> None: super().__init__(model, request) self.breadcrumbs.append( (_('Screens'), request.link(self.model), ''), diff --git a/src/onegov/election_day/layouts/vote.py b/src/onegov/election_day/layouts/vote.py index bdaedec2b9..59be50e277 100644 --- a/src/onegov/election_day/layouts/vote.py +++ b/src/onegov/election_day/layouts/vote.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.utils import normalize_for_url from onegov.election_day import _ @@ -17,12 +19,12 @@ class VoteLayout(DetailLayout): - model: 'Vote' + model: Vote def __init__( self, - model: 'Vote', - request: 'ElectionDayRequest', + model: Vote, + request: ElectionDayRequest, tab: str = 'entities' ) -> None: super().__init__(model, request) @@ -188,7 +190,7 @@ def scope(self) -> str | None: return None @cached_property - def ballot(self) -> 'Ballot': + def ballot(self) -> Ballot: if self.type == 'complex' and 'counter' in self.tab: return self.model.counter_proposal # type:ignore[attr-defined] if self.type == 'complex' and 'tie-breaker' in self.tab: @@ -275,7 +277,7 @@ def direct(self) -> bool: return self.model.direct @cached_property - def menu(self) -> 'NestedMenu': + def menu(self) -> NestedMenu: if self.type == 'complex': result: NestedMenu = [] diff --git a/src/onegov/election_day/models/__init__.py b/src/onegov/election_day/models/__init__.py index 6be5b70b2e..c264444a9c 100644 --- a/src/onegov/election_day/models/__init__.py +++ b/src/onegov/election_day/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models.archived_result import ArchivedResult from onegov.election_day.models.data_source import DataSource from onegov.election_day.models.data_source import DataSourceItem diff --git a/src/onegov/election_day/models/archived_result.py b/src/onegov/election_day/models/archived_result.py index c13cfbf681..5ac87f56b4 100644 --- a/src/onegov/election_day/models/archived_result.py +++ b/src/onegov/election_day/models/archived_result.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from copy import deepcopy from onegov.core.orm import Base from onegov.core.orm import translation_hybrid @@ -49,29 +51,29 @@ class ArchivedResult(Base, ContentMixin, TimestampMixin, __tablename__ = 'archived_results' #: Identifies the result - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The date of the election/vote - date: 'Column[datetime.date]' = Column(Date, nullable=False) + date: Column[datetime.date] = Column(Date, nullable=False) #: The last change of the results election/vote - last_modified: 'Column[datetime.datetime | None]' = Column( + last_modified: Column[datetime.datetime | None] = Column( UTCDateTime, nullable=True ) #: The last change of election/vote - last_result_change: 'Column[datetime.datetime | None]' = Column( + last_result_change: Column[datetime.datetime | None] = Column( UTCDateTime, nullable=True ) #: Type of the result - type: 'Column[ResultType]' = Column( + type: Column[ResultType] = Column( Enum( # type:ignore[arg-type] 'vote', 'election', 'election_compound', name='type_of_result' @@ -80,42 +82,42 @@ class ArchivedResult(Base, ContentMixin, TimestampMixin, ) #: Origin of the result - schema: 'Column[str]' = Column(Text, nullable=False) + schema: Column[str] = Column(Text, nullable=False) #: The name of the principal - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: Total number of political entities - total_entities: 'Column[int | None]' = Column(Integer, nullable=True) + total_entities: Column[int | None] = Column(Integer, nullable=True) #: Number of already counted political entities - counted_entities: 'Column[int | None]' = Column(Integer, nullable=True) + counted_entities: Column[int | None] = Column(Integer, nullable=True) @property def progress(self) -> tuple[int, int]: return self.counted_entities or 0, self.total_entities or 0 #: Number of already counted political entities - has_results: 'Column[bool | None]' = Column(Boolean, nullable=True) + has_results: Column[bool | None] = Column(Boolean, nullable=True) #: The link to the detailed results - url: 'Column[str]' = Column(Text, nullable=False) + url: Column[str] = Column(Text, nullable=False) #: Title of the election/vote - title_translations: 'Column[Mapping[str, str]]' = Column( + title_translations: Column[Mapping[str, str]] = Column( HSTORE, nullable=False ) title = translation_hybrid(title_translations) - def title_prefix(self, request: 'ElectionDayRequest') -> str: + def title_prefix(self, request: ElectionDayRequest) -> str: if self.is_fetched(request) and self.domain == 'municipality': return self.name or '' return '' #: Shortcode for cantons that use it - shortcode: 'Column[str | None]' = Column(Text, nullable=True) + shortcode: Column[str | None] = Column(Text, nullable=True) #: The id of the election/vote. external_id: dict_property[str | None] = meta_property('id') @@ -187,7 +189,7 @@ def title_prefix(self, request: 'ElectionDayRequest') -> str: ) @property - def type_class(self) -> '_type[Election | ElectionCompound | Vote]': + def type_class(self) -> _type[Election | ElectionCompound | Vote]: if self.type == 'vote': return Vote elif self.type == 'election': @@ -196,7 +198,7 @@ def type_class(self) -> '_type[Election | ElectionCompound | Vote]': return ElectionCompound raise NotImplementedError - def is_fetched(self, request: 'ElectionDayRequest') -> bool: + def is_fetched(self, request: ElectionDayRequest) -> bool: """ Returns True, if this results has been fetched from another instance. @@ -205,7 +207,7 @@ def is_fetched(self, request: 'ElectionDayRequest') -> bool: def is_fetched_by_municipality( self, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> bool: """ Returns True, if this results has been fetched from another instance by a communal instance. @@ -216,7 +218,7 @@ def is_fetched_by_municipality( and request.app.principal.domain == 'municipality' ) - def adjusted_url(self, request: 'ElectionDayRequest') -> str: + def adjusted_url(self, request: ElectionDayRequest) -> str: """ Returns the url adjusted to the current host. Needed if the instance is accessible under different hosts at the same time. @@ -229,28 +231,28 @@ def adjusted_url(self, request: 'ElectionDayRequest') -> str: {'id': self.external_id} ) - def display_answer(self, request: 'ElectionDayRequest') -> str: + def display_answer(self, request: ElectionDayRequest) -> str: """ Returns the answer (depending on the current instance). """ if self.is_fetched_by_municipality(request): return self.local_answer return self.answer - def display_nays_percentage(self, request: 'ElectionDayRequest') -> float: + def display_nays_percentage(self, request: ElectionDayRequest) -> float: """ Returns the nays rate (depending on the current instance). """ if self.is_fetched_by_municipality(request): return self.local_nays_percentage return self.nays_percentage - def display_yeas_percentage(self, request: 'ElectionDayRequest') -> float: + def display_yeas_percentage(self, request: ElectionDayRequest) -> float: """ Returns the yeas rate (depending on the current instance). """ if self.is_fetched_by_municipality(request): return self.local_yeas_percentage return self.yeas_percentage - def copy_from(self, source: 'Self') -> None: + def copy_from(self, source: Self) -> None: self.date = source.date self.last_modified = source.last_modified self.last_result_change = source.last_result_change diff --git a/src/onegov/election_day/models/data_source.py b/src/onegov/election_day/models/data_source.py index 3b4b616c9a..9e96a6f6c2 100644 --- a/src/onegov/election_day/models/data_source.py +++ b/src/onegov/election_day/models/data_source.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -38,24 +40,24 @@ class DataSource(Base, TimestampMixin): __tablename__ = 'upload_data_source' #: Identifies the data source - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The name of the upload configuration - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: The token used to authenticate - token: 'Column[uuid.UUID]' = Column( + token: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] nullable=False, default=uuid4 ) #: The type of upload - type: 'Column[UploadType]' = Column( + type: Column[UploadType] = Column( Enum( # type:ignore[arg-type] 'vote', 'majorz', @@ -66,7 +68,7 @@ class DataSource(Base, TimestampMixin): ) #: A configuration may contain n items - items: 'relationship[AppenderQuery[DataSourceItem]]' = relationship( + items: relationship[AppenderQuery[DataSourceItem]] = relationship( 'DataSourceItem', cascade='all, delete-orphan', lazy='dynamic', @@ -77,7 +79,7 @@ class DataSource(Base, TimestampMixin): def label(self) -> str: return dict(UPLOAD_TYPE_LABELS)[self.type] - def query_candidates(self) -> 'Query[Election | Vote]': + def query_candidates(self) -> Query[Election | Vote]: """ Returns a list of available votes or elections matching the type of the source. """ @@ -107,50 +109,50 @@ class DataSourceItem(Base, TimestampMixin): __tablename__ = 'upload_data_source_item' - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the upload configuration result belongs to - source_id: 'Column[uuid.UUID]' = Column( + source_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey(DataSource.id), nullable=False ) #: the district - district: 'Column[str | None]' = Column(Text, nullable=True) + district: Column[str | None] = Column(Text, nullable=True) #: the vote / election number - number: 'Column[str | None]' = Column(Text, nullable=True) + number: Column[str | None] = Column(Text, nullable=True) #: the election - election_id: 'Column[str | None]' = Column( + election_id: Column[str | None] = Column( Text, ForeignKey(Election.id, onupdate='CASCADE'), nullable=True ) - election: 'relationship[Election | None]' = relationship( + election: relationship[Election | None] = relationship( 'Election', back_populates='data_sources' ) #: the vote - vote_id: 'Column[str | None]' = Column( + vote_id: Column[str | None] = Column( Text, ForeignKey(Vote.id, onupdate='CASCADE'), nullable=True ) - vote: 'relationship[Vote | None]' = relationship( + vote: relationship[Vote | None] = relationship( 'Vote', back_populates='data_sources' ) - source: 'relationship[DataSource]' = relationship( + source: relationship[DataSource] = relationship( DataSource, back_populates='items' ) diff --git a/src/onegov/election_day/models/election/__init__.py b/src/onegov/election_day/models/election/__init__.py index c8e4e7d781..da5cd92d16 100644 --- a/src/onegov/election_day/models/election/__init__.py +++ b/src/onegov/election_day/models/election/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models.election.candidate import Candidate from onegov.election_day.models.election.candidate_panachage_result import \ CandidatePanachageResult diff --git a/src/onegov/election_day/models/election/candidate.py b/src/onegov/election_day/models/election/candidate.py index 986f9eb941..dd6d7bb878 100644 --- a/src/onegov/election_day/models/election/candidate.py +++ b/src/onegov/election_day/models/election/candidate.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -39,26 +41,26 @@ class Candidate(Base, TimestampMixin): __tablename__ = 'candidates' #: the internal id of the candidate - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the external id of the candidate - candidate_id: 'Column[str]' = Column(Text, nullable=False) + candidate_id: Column[str] = Column(Text, nullable=False) #: the family name - family_name: 'Column[str]' = Column(Text, nullable=False) + family_name: Column[str] = Column(Text, nullable=False) #: the first name - first_name: 'Column[str]' = Column(Text, nullable=False) + first_name: Column[str] = Column(Text, nullable=False) #: True if the candidate is elected - elected: 'Column[bool]' = Column(Boolean, nullable=False) + elected: Column[bool] = Column(Boolean, nullable=False) #: the gender - gender: 'Column[Gender | None]' = Column( + gender: Column[Gender | None] = Column( Enum( # type:ignore[arg-type] 'male', 'female', @@ -69,46 +71,46 @@ class Candidate(Base, TimestampMixin): ) #: the year of birth - year_of_birth: 'Column[int | None]' = Column(Integer, nullable=True) + year_of_birth: Column[int | None] = Column(Integer, nullable=True) #: the election id this candidate belongs to - election_id: 'Column[str]' = Column( + election_id: Column[str] = Column( Text, ForeignKey('elections.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=False ) #: the election this candidate belongs to - election: 'relationship[Election]' = relationship( + election: relationship[Election] = relationship( 'Election', back_populates='candidates' ) #: the list id this candidate belongs to - list_id: 'Column[uuid.UUID | None]' = Column( + list_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey('lists.id', ondelete='CASCADE'), nullable=True ) #: the list this candidate belongs to - list: 'relationship[List]' = relationship( + list: relationship[List] = relationship( 'List', back_populates='candidates' ) #: the party name - party: 'Column[str | None]' = Column(Text, nullable=True) + party: Column[str | None] = Column(Text, nullable=True) #: a candidate contains n results - results: 'relationship[list_t[CandidateResult]]' = relationship( + results: relationship[list_t[CandidateResult]] = relationship( 'CandidateResult', cascade='all, delete-orphan', back_populates='candidate' ) #: a (proporz) candidate contains votes from other other lists - panachage_results: 'relationship[list_t[CandidatePanachageResult]]' + panachage_results: relationship[list_t[CandidatePanachageResult]] panachage_results = relationship( 'CandidatePanachageResult', cascade='all, delete-orphan', @@ -126,7 +128,7 @@ def aggregate_results(self, attribute: str) -> int: def aggregate_results_expression( cls, attribute: str - ) -> 'ColumnElement[int]': + ) -> ColumnElement[int]: """ Gets the sum of the given attribute from the results, as SQL expression. @@ -142,7 +144,7 @@ def aggregate_results_expression( return expr.label(attribute) @property - def percentage_by_entity(self) -> dict[int, 'EntityPercentage']: + def percentage_by_entity(self) -> dict[int, EntityPercentage]: """ Returns the percentage of votes by the entity. Includes uncounted entities and entities with no results available. @@ -207,7 +209,7 @@ def percentage_by_entity(self) -> dict[int, 'EntityPercentage']: return percentage @property - def percentage_by_district(self) -> dict[str, 'DistrictPercentage']: + def percentage_by_district(self) -> dict[str, DistrictPercentage]: """ Returns the percentage of votes aggregated by the distict. Includes uncounted districts and districts with no results available. diff --git a/src/onegov/election_day/models/election/candidate_panachage_result.py b/src/onegov/election_day/models/election/candidate_panachage_result.py index 26f0c7d058..0a2fab1db4 100644 --- a/src/onegov/election_day/models/election/candidate_panachage_result.py +++ b/src/onegov/election_day/models/election/candidate_panachage_result.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -21,50 +23,50 @@ class CandidatePanachageResult(Base, TimestampMixin): __tablename__ = 'candidate_panachage_results' #: identifies the result - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the election result id this result belongs to - election_result_id: 'Column[uuid.UUID]' = Column( + election_result_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('election_results.id', ondelete='CASCADE'), nullable=False ) #: the election result this result belongs to - election_result: 'relationship[ElectionResult]' = relationship( + election_result: relationship[ElectionResult] = relationship( 'ElectionResult', back_populates='candidate_panachage_results' ) #: the candidate id this result belongs to - target_id: 'Column[uuid.UUID]' = Column( + target_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('candidates.id', ondelete='CASCADE'), nullable=False ) #: the candidate this result belongs to - candidate: 'relationship[Candidate]' = relationship( + candidate: relationship[Candidate] = relationship( 'Candidate', back_populates='panachage_results' ) #: the list id this result belongs to, empty in case of the blank list - source_id: 'Column[uuid.UUID | None]' = Column( + source_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey('lists.id', ondelete='CASCADE'), nullable=True ) #: the list id this result belongs to, empty in case of the blank list - list: 'relationship[List] | None' = relationship( + list: relationship[List] | None = relationship( 'List', back_populates='candidate_panachage_results' ) #: the number of votes - votes: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0) + votes: Column[int] = Column(Integer, nullable=False, default=lambda: 0) diff --git a/src/onegov/election_day/models/election/candidate_result.py b/src/onegov/election_day/models/election/candidate_result.py index 505352c8a4..caa22749e7 100644 --- a/src/onegov/election_day/models/election/candidate_result.py +++ b/src/onegov/election_day/models/election/candidate_result.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -21,37 +23,37 @@ class CandidateResult(Base, TimestampMixin): __tablename__ = 'candidate_results' #: identifies the candidate result - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) # votes - votes: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0) + votes: Column[int] = Column(Integer, nullable=False, default=lambda: 0) #: the election result id this result belongs to - election_result_id: 'Column[uuid.UUID]' = Column( + election_result_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('election_results.id', ondelete='CASCADE'), nullable=False ) #: the election result this result belongs to - election_result: 'relationship[ElectionResult]' = relationship( + election_result: relationship[ElectionResult] = relationship( 'ElectionResult', back_populates='candidate_results' ) #: the candidate id this result belongs to - candidate_id: 'Column[uuid.UUID]' = Column( + candidate_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('candidates.id', ondelete='CASCADE'), nullable=False ) #: the candidate this result belongs to - candidate: 'relationship[Candidate]' = relationship( + candidate: relationship[Candidate] = relationship( 'Candidate', back_populates='results' ) diff --git a/src/onegov/election_day/models/election/election.py b/src/onegov/election_day/models/election/election.py index 38e93822fc..0f6ad4505e 100644 --- a/src/onegov/election_day/models/election/election.py +++ b/src/onegov/election_day/models/election/election.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base, observes from onegov.core.orm import translation_hybrid from onegov.core.orm.mixins import ContentMixin @@ -58,14 +60,14 @@ class Election(Base, ContentMixin, LastModifiedMixin, __tablename__ = 'elections' @property - def polymorphic_base(self) -> type['Election']: + def polymorphic_base(self) -> type[Election]: return Election #: the type of the item, this can be used to create custom polymorphic #: subclasses of this class. See #: ``_. - type: 'Column[str]' = Column(Text, nullable=False) + type: Column[str] = Column(Text, nullable=False) __mapper_args__ = { 'polymorphic_on': type, @@ -73,13 +75,13 @@ def polymorphic_base(self) -> type['Election']: } #: Identifies the election, may be used in the url - id: 'Column[str]' = Column(Text, primary_key=True) + id: Column[str] = Column(Text, primary_key=True) #: external identifier - external_id: 'Column[str | None]' = Column(Text, nullable=True) + external_id: Column[str | None] = Column(Text, nullable=True) #: all translations of the title - title_translations: 'Column[Mapping[str, str]]' = Column( + title_translations: Column[Mapping[str, str]] = Column( HSTORE, nullable=False ) @@ -89,7 +91,7 @@ def polymorphic_base(self) -> type['Election']: title = translation_hybrid(title_translations) #: all translations of the short title - short_title_translations: 'Column[Mapping[str, str] | None]' = Column( + short_title_translations: Column[Mapping[str, str] | None] = Column( HSTORE, nullable=True ) @@ -101,20 +103,20 @@ def polymorphic_base(self) -> type['Election']: @observes('title_translations', 'short_title_translations') def title_observer( self, - title_translations: 'Mapping[str, str]', - short_title_translations: 'Mapping[str, str]' + title_translations: Mapping[str, str], + short_title_translations: Mapping[str, str] ) -> None: if not self.id: self.id = self.id_from_title(object_session(self)) #: Shortcode for cantons that use it - shortcode: 'Column[str | None]' = Column(Text, nullable=True) + shortcode: Column[str | None] = Column(Text, nullable=True) #: The date of the election - date: 'Column[datetime.date]' = Column(Date, nullable=False) + date: Column[datetime.date] = Column(Date, nullable=False) #: Number of mandates - number_of_mandates: 'Column[int]' = Column( + number_of_mandates: Column[int] = Column( Integer, nullable=False, default=lambda: 0 @@ -134,7 +136,7 @@ def allocated_mandates(self) -> int: majority_type: dict_property[str | None] = meta_property('majority_type') #: Absolute majority - absolute_majority: 'Column[int | None]' = Column(Integer, nullable=True) + absolute_majority: Column[int | None] = Column(Integer, nullable=True) if TYPE_CHECKING: counted: Column[bool] @@ -149,7 +151,7 @@ def counted(self) -> bool: return all(r.counted for r in self.results) @counted.expression # type:ignore[no-redef] - def counted(cls) -> 'ColumnElement[bool]': + def counted(cls) -> ColumnElement[bool]: expr = select([ func.coalesce(func.bool_and(ElectionResult.counted), False) ]) @@ -188,7 +190,7 @@ def has_results(self) -> bool: return False #: An election contains n candidates - candidates: 'relationship[list[Candidate]]' = relationship( + candidates: relationship[list[Candidate]] = relationship( 'Candidate', cascade='all, delete-orphan', back_populates='election', @@ -196,7 +198,7 @@ def has_results(self) -> bool: ) #: An election contains n results, one for each political entity - results: 'relationship[list[ElectionResult]]' = relationship( + results: relationship[list[ElectionResult]] = relationship( 'ElectionResult', cascade='all, delete-orphan', back_populates='election', @@ -204,7 +206,7 @@ def has_results(self) -> bool: ) @property - def results_query(self) -> 'Query[ElectionResult]': + def results_query(self) -> Query[ElectionResult]: session = object_session(self) query = session.query(ElectionResult) query = query.filter(ElectionResult.election_id == self.id) @@ -212,7 +214,7 @@ def results_query(self) -> 'Query[ElectionResult]': return query #: An election may have related elections - related_elections: 'relationship[AppenderQuery[ElectionRelationship]]' + related_elections: relationship[AppenderQuery[ElectionRelationship]] related_elections = relationship( 'ElectionRelationship', foreign_keys='ElectionRelationship.source_id', @@ -222,7 +224,7 @@ def results_query(self) -> 'Query[ElectionResult]': ) #: An election may be related by other elections - referencing_elections: 'relationship[AppenderQuery[ElectionRelationship]]' + referencing_elections: relationship[AppenderQuery[ElectionRelationship]] referencing_elections = relationship( 'ElectionRelationship', foreign_keys='ElectionRelationship.target_id', @@ -232,14 +234,14 @@ def results_query(self) -> 'Query[ElectionResult]': ) #: An election may be part of an election compound - election_compound_id: 'Column[str | None]' = Column( + election_compound_id: Column[str | None] = Column( Text, ForeignKey('election_compounds.id', onupdate='CASCADE'), nullable=True ) #: The election compound this election belongs to - election_compound: 'relationship[ElectionCompound]' = relationship( + election_compound: relationship[ElectionCompound] = relationship( 'ElectionCompound', back_populates='elections' ) @@ -287,7 +289,7 @@ def aggregate_results(self, attribute: str) -> int: def aggregate_results_expression( cls, attribute: str - ) -> 'ColumnElement[int]': + ) -> ColumnElement[int]: """ Gets the sum of the given attribute from the results, as SQL expression. @@ -342,7 +344,7 @@ def elected_candidates(self) -> list[tuple[str, str]]: ) @property - def votes_by_district(self) -> 'Query[VotesByDistrictRow]': + def votes_by_district(self) -> Query[VotesByDistrictRow]: query = self.results_query.order_by(None) results = query.with_entities( self.__class__.id.label('election_id'), @@ -386,13 +388,13 @@ def clear_results(self, clear_all: bool = False) -> None: session.expire_all() #: data source items linked to this election - data_sources: 'relationship[list[DataSourceItem]]' = relationship( + data_sources: relationship[list[DataSourceItem]] = relationship( 'DataSourceItem', back_populates='election' ) #: notifcations linked to this election - notifications: 'relationship[AppenderQuery[Notification]]' + notifications: relationship[AppenderQuery[Notification]] notifications = relationship( # type:ignore[misc] 'onegov.election_day.models.notification.Notification', back_populates='election', @@ -400,7 +402,7 @@ def clear_results(self, clear_all: bool = False) -> None: ) #: screens linked to this election - screens: 'relationship[AppenderQuery[Screen]]' = relationship( + screens: relationship[AppenderQuery[Screen]] = relationship( 'Screen', back_populates='election', ) diff --git a/src/onegov/election_day/models/election/election_result.py b/src/onegov/election_day/models/election/election_result.py index ac488133d2..e18a557bbf 100644 --- a/src/onegov/election_day/models/election/election_result.py +++ b/src/onegov/election_day/models/election/election_result.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -30,91 +32,91 @@ class ElectionResult(Base, TimestampMixin, DerivedAttributesMixin): __tablename__ = 'election_results' #: identifies the result - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the election id this result belongs to - election_id: 'Column[str]' = Column( + election_id: Column[str] = Column( Text, ForeignKey('elections.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=False ) #: the election this candidate belongs to - election: 'relationship[Election]' = relationship( + election: relationship[Election] = relationship( 'Election', back_populates='results' ) #: entity id (e.g. a BFS number). - entity_id: 'Column[int]' = Column(Integer, nullable=False) + entity_id: Column[int] = Column(Integer, nullable=False) #: the name of the entity - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: the district this entity belongs to - district: 'Column[str | None]' = Column(Text, nullable=True) + district: Column[str | None] = Column(Text, nullable=True) #: the superregion this entity belongs to - superregion: 'Column[str | None]' = Column(Text, nullable=True) + superregion: Column[str | None] = Column(Text, nullable=True) #: True if the result has been counted and no changes will be made anymore. #: If the result is definite, all the values below must be specified. - counted: 'Column[bool]' = Column(Boolean, nullable=False) + counted: Column[bool] = Column(Boolean, nullable=False) #: number of eligible voters - eligible_voters: 'Column[int]' = Column( + eligible_voters: Column[int] = Column( Integer, nullable=False, default=lambda: 0 ) #: number of expats - expats: 'Column[int | None]' = Column( + expats: Column[int | None] = Column( Integer, nullable=True ) #: number of received ballots - received_ballots: 'Column[int]' = Column( + received_ballots: Column[int] = Column( Integer, nullable=False, default=lambda: 0 ) #: number of blank ballots - blank_ballots: 'Column[int]' = Column( + blank_ballots: Column[int] = Column( Integer, nullable=False, default=lambda: 0 ) #: number of invalid ballots - invalid_ballots: 'Column[int]' = Column( + invalid_ballots: Column[int] = Column( Integer, nullable=False, default=lambda: 0 ) #: number of blank votes - blank_votes: 'Column[int]' = Column( + blank_votes: Column[int] = Column( Integer, nullable=False, default=lambda: 0 ) #: number of invalid votes - invalid_votes: 'Column[int]' = Column( + invalid_votes: Column[int] = Column( Integer, nullable=False, default=lambda: 0 ) if TYPE_CHECKING: - accounted_votes: 'Column[int]' + accounted_votes: Column[int] @hybrid_property # type:ignore[no-redef] def accounted_votes(self) -> int: @@ -127,7 +129,7 @@ def accounted_votes(self) -> int: ) @accounted_votes.expression # type:ignore[no-redef] - def accounted_votes(cls) -> 'ColumnElement[int]': + def accounted_votes(cls) -> ColumnElement[int]: """ The number of accounted votes. """ from onegov.election_day.models import Election # circular @@ -143,21 +145,21 @@ def accounted_votes(cls) -> 'ColumnElement[int]': ) #: an election result may contain n list results - list_results: 'relationship[list[ListResult]]' = relationship( + list_results: relationship[list[ListResult]] = relationship( 'ListResult', cascade='all, delete-orphan', back_populates='election_result' ) #: an election result contains n candidate results - candidate_results: 'relationship[list[CandidateResult]]' = relationship( + candidate_results: relationship[list[CandidateResult]] = relationship( 'CandidateResult', cascade='all, delete-orphan', back_populates='election_result' ) #: an election result contains n candidate panachage results - candidate_panachage_results: 'relationship[list[CandidatePanachageResult]]' + candidate_panachage_results: relationship[list[CandidatePanachageResult]] candidate_panachage_results = relationship( 'CandidatePanachageResult', cascade='all, delete-orphan', diff --git a/src/onegov/election_day/models/election/list.py b/src/onegov/election_day/models/election/list.py index 39043d8162..0ac9877e3d 100644 --- a/src/onegov/election_day/models/election/list.py +++ b/src/onegov/election_day/models/election/list.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -34,67 +36,67 @@ class List(Base, TimestampMixin): __tablename__ = 'lists' #: internal id of the list - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: external id of the list - list_id: 'Column[str]' = Column(Text, nullable=False) + list_id: Column[str] = Column(Text, nullable=False) # number of mandates - number_of_mandates: 'Column[int]' = Column( + number_of_mandates: Column[int] = Column( Integer, nullable=False, default=lambda: 0 ) #: name of the list - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: the election id this list belongs to - election_id: 'Column[str]' = Column( + election_id: Column[str] = Column( Text, ForeignKey('elections.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=False ) #: the election this list belongs to - election: 'relationship[ProporzElection]' = relationship( + election: relationship[ProporzElection] = relationship( 'ProporzElection', back_populates='lists' ) #: the list connection id this list belongs to - connection_id: 'Column[uuid.UUID | None]' = Column( + connection_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey('list_connections.id', ondelete='CASCADE'), nullable=True ) #: the list connection this list belongs to - connection: 'relationship[ListConnection]' = relationship( + connection: relationship[ListConnection] = relationship( 'ListConnection', back_populates='lists' ) #: a list contains n candidates - candidates: 'relationship[list[Candidate]]' = relationship( + candidates: relationship[list[Candidate]] = relationship( 'Candidate', cascade='all, delete-orphan', back_populates='list', ) #: a list contains n results - results: 'relationship[list[ListResult]]' = relationship( + results: relationship[list[ListResult]] = relationship( 'ListResult', cascade='all, delete-orphan', back_populates='list', ) #: a list contains additional votes from other lists - panachage_results: 'relationship[list[ListPanachageResult]]' + panachage_results: relationship[list[ListPanachageResult]] panachage_results = relationship( 'ListPanachageResult', foreign_keys='ListPanachageResult.target_id', @@ -103,7 +105,7 @@ class List(Base, TimestampMixin): ) #: a list contains to other lists lost votes - panachage_results_lost: 'relationship[list[ListPanachageResult]]' + panachage_results_lost: relationship[list[ListPanachageResult]] panachage_results_lost = relationship( 'ListPanachageResult', foreign_keys='ListPanachageResult.source_id', @@ -112,7 +114,7 @@ class List(Base, TimestampMixin): ) #: an list contains n (outgoing) candidate panachage results - candidate_panachage_results: 'relationship[list[CandidatePanachageResult]]' + candidate_panachage_results: relationship[list[CandidatePanachageResult]] candidate_panachage_results = relationship( 'CandidatePanachageResult', cascade='all, delete-orphan', @@ -131,7 +133,7 @@ def aggregate_results(self, attribute: str) -> int: def aggregate_results_expression( cls, attribute: str - ) -> 'ColumnElement[int]': + ) -> ColumnElement[int]: """ Gets the sum of the given attribute from the results, as SQL expression. @@ -147,7 +149,7 @@ def aggregate_results_expression( return expr.label(attribute) @property - def percentage_by_entity(self) -> dict[int, 'EntityPercentage']: + def percentage_by_entity(self) -> dict[int, EntityPercentage]: """ Returns the percentage of votes by the entity. Includes uncounted entities and entities with no results available. @@ -201,7 +203,7 @@ def percentage_by_entity(self) -> dict[int, 'EntityPercentage']: return percentage @property - def percentage_by_district(self) -> dict[str, 'DistrictPercentage']: + def percentage_by_district(self) -> dict[str, DistrictPercentage]: """ Returns the percentage of votes aggregated by the distict. Includes uncounted districts and districts with no results available. diff --git a/src/onegov/election_day/models/election/list_connection.py b/src/onegov/election_day/models/election/list_connection.py index 1dab162261..882384b9b0 100644 --- a/src/onegov/election_day/models/election/list_connection.py +++ b/src/onegov/election_day/models/election/list_connection.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -27,44 +29,44 @@ class ListConnection(Base, TimestampMixin): __tablename__ = 'list_connections' #: internal id of the list - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: external id of the list - connection_id: 'Column[str]' = Column(Text, nullable=False) + connection_id: Column[str] = Column(Text, nullable=False) #: the election id this result belongs to - election_id: 'Column[str | None]' = Column( + election_id: Column[str | None] = Column( Text, ForeignKey('elections.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=True ) #: the election this result belongs to - election: 'relationship[ProporzElection]' = relationship( + election: relationship[ProporzElection] = relationship( 'ProporzElection', back_populates='list_connections' ) #: ID of the parent list connection - parent_id: 'Column[uuid.UUID | None]' = Column( + parent_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey('list_connections.id'), nullable=True ) # the parent - parent: 'relationship[ListConnection]' = relationship( + parent: relationship[ListConnection] = relationship( 'ListConnection', back_populates='children', remote_side='ListConnection.id' ) #: a list connection contains n lists - lists: 'relationship[list[List]]' = relationship( + lists: relationship[list[List]] = relationship( 'List', cascade='all, delete-orphan', back_populates='connection', @@ -72,7 +74,7 @@ class ListConnection(Base, TimestampMixin): ) #: a list connection contains n sub-connection - children: 'relationship[AppenderQuery[ListConnection]]' = relationship( + children: relationship[AppenderQuery[ListConnection]] = relationship( 'ListConnection', cascade='all, delete-orphan', back_populates='parent', @@ -108,7 +110,7 @@ def aggregate_results(self, attribute: str) -> int: def aggregate_results_expression( cls, attribute: str - ) -> 'ColumnElement[int]': + ) -> ColumnElement[int]: """ Gets the sum of the given attribute from the results, as SQL expression. diff --git a/src/onegov/election_day/models/election/list_panachage_result.py b/src/onegov/election_day/models/election/list_panachage_result.py index 1c2049a30a..4f872791b6 100644 --- a/src/onegov/election_day/models/election/list_panachage_result.py +++ b/src/onegov/election_day/models/election/list_panachage_result.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -19,39 +21,39 @@ class ListPanachageResult(Base, TimestampMixin): __tablename__ = 'list_panachage_results' #: identifies the result - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the target list id this result belongs to - target_id: 'Column[uuid.UUID]' = Column( + target_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('lists.id', ondelete='CASCADE'), nullable=False ) #: the target list this result belongs to - target: 'relationship[List]' = relationship( + target: relationship[List] = relationship( 'List', foreign_keys='ListPanachageResult.target_id', back_populates='panachage_results' ) #: the source list id this result belongs to, empty if blank list - source_id: 'Column[uuid.UUID | None]' = Column( + source_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey('lists.id', ondelete='CASCADE'), nullable=True ) #: the source list this result belongs to, empty if blank list - source: 'relationship[List]' = relationship( + source: relationship[List] = relationship( 'List', foreign_keys='ListPanachageResult.source_id', back_populates='panachage_results_lost' ) #: the number of votes - votes: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0) + votes: Column[int] = Column(Integer, nullable=False, default=lambda: 0) diff --git a/src/onegov/election_day/models/election/list_result.py b/src/onegov/election_day/models/election/list_result.py index 8c04ef13f6..0f6f12831a 100644 --- a/src/onegov/election_day/models/election/list_result.py +++ b/src/onegov/election_day/models/election/list_result.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -21,37 +23,37 @@ class ListResult(Base, TimestampMixin): __tablename__ = 'list_results' #: identifies the list - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) # votes - votes: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0) + votes: Column[int] = Column(Integer, nullable=False, default=lambda: 0) #: the election result id this result belongs to - election_result_id: 'Column[uuid.UUID]' = Column( + election_result_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('election_results.id', ondelete='CASCADE'), nullable=False ) #: the election result this result belongs to - election_result: 'relationship[ElectionResult]' = relationship( + election_result: relationship[ElectionResult] = relationship( 'ElectionResult', back_populates='list_results' ) #: the list id this result belongs to - list_id: 'Column[uuid.UUID]' = Column( + list_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('lists.id', ondelete='CASCADE'), nullable=False ) #: the list this result belongs to - list: 'relationship[List]' = relationship( + list: relationship[List] = relationship( 'List', back_populates='results' ) diff --git a/src/onegov/election_day/models/election/mixins.py b/src/onegov/election_day/models/election/mixins.py index 337efeaf8b..53cbac14a9 100644 --- a/src/onegov/election_day/models/election/mixins.py +++ b/src/onegov/election_day/models/election/mixins.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sqlalchemy import case from sqlalchemy import cast from sqlalchemy import Float diff --git a/src/onegov/election_day/models/election/proporz_election.py b/src/onegov/election_day/models/election/proporz_election.py index 595a4a2219..7e9f8c0852 100644 --- a/src/onegov/election_day/models/election/proporz_election.py +++ b/src/onegov/election_day/models/election/proporz_election.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models.election.candidate_panachage_result import \ CandidatePanachageResult from onegov.election_day.models.election.election import Election @@ -43,7 +45,7 @@ class ProporzElection( } #: An election contains n list connections - list_connections: 'relationship[list[ListConnection]]' = relationship( + list_connections: relationship[list[ListConnection]] = relationship( 'ListConnection', cascade='all, delete-orphan', back_populates='election', @@ -51,21 +53,21 @@ class ProporzElection( ) #: An election contains n lists - lists: 'relationship[list[List]]' = relationship( + lists: relationship[list[List]] = relationship( 'List', cascade='all, delete-orphan', back_populates='election', ) #: An election may contains n party results - party_results: 'relationship[list[PartyResult]]' = relationship( + party_results: relationship[list[PartyResult]] = relationship( 'PartyResult', cascade='all, delete-orphan', back_populates='election' ) #: An election may contains n party panachage results - party_panachage_results: 'relationship[list[PartyPanachageResult]]' + party_panachage_results: relationship[list[PartyPanachageResult]] party_panachage_results = relationship( 'PartyPanachageResult', cascade='all, delete-orphan', @@ -73,7 +75,7 @@ class ProporzElection( ) @property - def votes_by_entity(self) -> 'Query[VotesByEntityRow]': + def votes_by_entity(self) -> Query[VotesByEntityRow]: query = self.results_query.order_by(None) query = query.outerjoin(ListResult) results = query.with_entities( @@ -90,7 +92,7 @@ def votes_by_entity(self) -> 'Query[VotesByEntityRow]': return results @property - def votes_by_district(self) -> 'Query[VotesByDistrictRow]': + def votes_by_district(self) -> Query[VotesByDistrictRow]: query = self.results_query.order_by(None) query = query.outerjoin(ListResult) results = query.with_entities( @@ -134,7 +136,7 @@ def has_candidate_panachage_data(self) -> bool: @property def relationships_for_historical_party_results( self - ) -> 'AppenderQuery[ElectionRelationship]': + ) -> AppenderQuery[ElectionRelationship]: return self.related_elections def clear_results(self, clear_all: bool = False) -> None: diff --git a/src/onegov/election_day/models/election/relationship.py b/src/onegov/election_day/models/election/relationship.py index ca0adbf536..65d51a9d4e 100644 --- a/src/onegov/election_day/models/election/relationship.py +++ b/src/onegov/election_day/models/election/relationship.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.types import UUID from sqlalchemy import Column @@ -19,35 +21,35 @@ class ElectionRelationship(Base): __tablename__ = 'election_relationships' #: Identifies the relationship. - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The source election ID. - source_id: 'Column[str]' = Column( + source_id: Column[str] = Column( Text, ForeignKey('elections.id', onupdate='CASCADE'), nullable=False ) #: The target election ID. - target_id: 'Column[str]' = Column( + target_id: Column[str] = Column( Text, ForeignKey('elections.id', onupdate='CASCADE'), primary_key=True ) #: The source election. - source: 'relationship[Election]' = relationship( + source: relationship[Election] = relationship( 'Election', foreign_keys=[source_id], back_populates='related_elections' ) #: The target election. - target: 'relationship[Election]' = relationship( + target: relationship[Election] = relationship( 'Election', foreign_keys=[target_id], back_populates='referencing_elections' diff --git a/src/onegov/election_day/models/election_compound/__init__.py b/src/onegov/election_day/models/election_compound/__init__.py index 543e818f02..4f4f0769c8 100644 --- a/src/onegov/election_day/models/election_compound/__init__.py +++ b/src/onegov/election_day/models/election_compound/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models.election_compound.election_compound import \ ElectionCompound from onegov.election_day.models.election_compound.part import \ diff --git a/src/onegov/election_day/models/election_compound/election_compound.py b/src/onegov/election_day/models/election_compound/election_compound.py index 2283604fed..48d56cdde8 100644 --- a/src/onegov/election_day/models/election_compound/election_compound.py +++ b/src/onegov/election_day/models/election_compound/election_compound.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base, observes from onegov.core.orm import translation_hybrid from onegov.core.orm.mixins import ContentMixin @@ -54,17 +56,17 @@ class ElectionCompound( __tablename__ = 'election_compounds' @property - def polymorphic_base(self) -> type['ElectionCompound']: + def polymorphic_base(self) -> type[ElectionCompound]: return ElectionCompound #: Identifies the election compound, may be used in the url - id: 'Column[str]' = Column(Text, primary_key=True) + id: Column[str] = Column(Text, primary_key=True) #: external identifier - external_id: 'Column[str | None]' = Column(Text, nullable=True) + external_id: Column[str | None] = Column(Text, nullable=True) #: all translations of the title - title_translations: 'Column[Mapping[str, str]]' = Column( + title_translations: Column[Mapping[str, str]] = Column( HSTORE, nullable=False ) @@ -74,7 +76,7 @@ def polymorphic_base(self) -> type['ElectionCompound']: title = translation_hybrid(title_translations) #: all translations of the short title - short_title_translations: 'Column[Mapping[str, str] | None]' = Column( + short_title_translations: Column[Mapping[str, str] | None] = Column( HSTORE, nullable=True ) @@ -86,44 +88,44 @@ def polymorphic_base(self) -> type['ElectionCompound']: @observes('title_translations', 'short_title_translations') def title_observer( self, - title_translations: 'Mapping[str, str]', - short_title_translations: 'Mapping[str, str]' + title_translations: Mapping[str, str], + short_title_translations: Mapping[str, str] ) -> None: if not self.id: self.id = self.id_from_title(object_session(self)) #: Shortcode for cantons that use it - shortcode: 'Column[str | None]' = Column(Text, nullable=True) + shortcode: Column[str | None] = Column(Text, nullable=True) #: The date of the elections - date: 'Column[datetime.date]' = Column(Date, nullable=False) + date: Column[datetime.date] = Column(Date, nullable=False) #: Doppelter Pukelsheim - pukelsheim: 'Column[bool]' = Column(Boolean, nullable=False, default=False) + pukelsheim: Column[bool] = Column(Boolean, nullable=False, default=False) #: Allow setting the status of the compound and its elections manually - completes_manually: 'Column[bool]' = Column( + completes_manually: Column[bool] = Column( Boolean, nullable=False, default=False ) #: Status of the compound and its elections - manually_completed: 'Column[bool]' = Column( + manually_completed: Column[bool] = Column( Boolean, nullable=False, default=False ) #: An election compound may contains n party results - party_results: 'relationship[list[PartyResult]]' = relationship( + party_results: relationship[list[PartyResult]] = relationship( 'PartyResult', cascade='all, delete-orphan', back_populates='election_compound' ) #: An election compound may contains n party panachage results - party_panachage_results: 'rel[list[PartyPanachageResult]]' + party_panachage_results: rel[list[PartyPanachageResult]] party_panachage_results = relationship( 'PartyPanachageResult', cascade='all, delete-orphan', @@ -131,7 +133,7 @@ def title_observer( ) #: An election compound may have related election compounds - related_compounds: 'rel[AppenderQuery[ElectionCompoundRelationship]]' + related_compounds: rel[AppenderQuery[ElectionCompoundRelationship]] related_compounds = relationship( 'ElectionCompoundRelationship', foreign_keys='ElectionCompoundRelationship.source_id', @@ -141,7 +143,7 @@ def title_observer( ) #: An election compound may be related by other election compounds - referencing_compounds: 'rel[AppenderQuery[ElectionCompoundRelationship]]' + referencing_compounds: rel[AppenderQuery[ElectionCompoundRelationship]] referencing_compounds = relationship( 'ElectionCompoundRelationship', foreign_keys='ElectionCompoundRelationship.target_id', @@ -157,13 +159,13 @@ def title_observer( ) #: Defines the domain of the elections - domain_elections: dict_property['DomainOfInfluence'] = meta_property( + domain_elections: dict_property[DomainOfInfluence] = meta_property( 'domain_elections', default='district' ) #: An election compound may contain n elections - elections: 'relationship[list[Election]]' = relationship( + elections: relationship[list[Election]] = relationship( 'Election', cascade='all', back_populates='election_compound', @@ -173,7 +175,7 @@ def title_observer( @observes('elections') def elections_observer( self, - elections: 'Collection[Election]' + elections: Collection[Election] ) -> None: changes = {c for e in elections if (c := e.last_result_change)} if changes: @@ -233,7 +235,7 @@ def elected_candidates(self) -> list[tuple[str, str]]: return result #: notifcations linked to this election compound - notifications: 'relationship[AppenderQuery[Notification]]' + notifications: relationship[AppenderQuery[Notification]] notifications = relationship( # type:ignore[misc] 'onegov.election_day.models.notification.Notification', back_populates='election_compound', @@ -241,7 +243,7 @@ def elected_candidates(self) -> list[tuple[str, str]]: ) #: screens linked to this election compound - screens: 'relationship[AppenderQuery[Screen]]' = relationship( + screens: relationship[AppenderQuery[Screen]] = relationship( 'Screen', back_populates='election_compound', ) @@ -263,7 +265,7 @@ def elected_candidates(self) -> list[tuple[str, str]]: @property def relationships_for_historical_party_results( self - ) -> 'AppenderQuery[ElectionCompoundRelationship]': + ) -> AppenderQuery[ElectionCompoundRelationship]: return self.related_compounds def clear_results(self, clear_all: bool = False) -> None: diff --git a/src/onegov/election_day/models/election_compound/mixins.py b/src/onegov/election_day/models/election_compound/mixins.py index 697260e1a9..dde0316d6d 100644 --- a/src/onegov/election_day/models/election_compound/mixins.py +++ b/src/onegov/election_day/models/election_compound/mixins.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import NamedTuple from typing import TYPE_CHECKING diff --git a/src/onegov/election_day/models/election_compound/part.py b/src/onegov/election_day/models/election_compound/part.py index 03b52a86f6..e56a38da66 100644 --- a/src/onegov/election_day/models/election_compound/part.py +++ b/src/onegov/election_day/models/election_compound/part.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models.election_compound.mixins import \ DerivedAttributesMixin from onegov.election_day.models.party_result.mixins import \ @@ -61,7 +63,7 @@ class ElectionCompoundPart( def __init__( self, - election_compound: 'ElectionCompound', + election_compound: ElectionCompound, domain: str, segment: str ): @@ -86,7 +88,7 @@ def __eq__(self, other: object) -> bool: # can be arbitrary readable attributes, which cannot be expressed # yet using a Protocol, once we can do that, this should become # cleaner - date: inherited_attribute['datetime.date'] = ( + date: inherited_attribute[datetime.date] = ( inherited_attribute['datetime.date']()) # type:ignore[assignment] completes_manually: inherited_attribute[bool] = ( inherited_attribute[bool]()) # type:ignore[assignment] @@ -133,7 +135,7 @@ def short_title_translations(self) -> dict[str, str]: } @property - def elections(self) -> list['Election']: + def elections(self) -> list[Election]: return [ election for election in self.election_compound.elections @@ -146,7 +148,7 @@ def progress(self) -> tuple[int, int]: return sum(1 for r in result if r), len(result) @property - def party_results(self) -> 'list[PartyResult]': # type:ignore[override] + def party_results(self) -> list[PartyResult]: # type:ignore[override] return [ result for result in self.election_compound.party_results if ( @@ -180,5 +182,5 @@ def elected_candidates(self) -> list[tuple[str, str]]: @property def relationships_for_historical_party_results( self - ) -> 'Query[ElectionCompoundRelationship]': + ) -> Query[ElectionCompoundRelationship]: return self.election_compound.related_compounds diff --git a/src/onegov/election_day/models/election_compound/relationship.py b/src/onegov/election_day/models/election_compound/relationship.py index 20cb15cdd8..a4c360157c 100644 --- a/src/onegov/election_day/models/election_compound/relationship.py +++ b/src/onegov/election_day/models/election_compound/relationship.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.types import UUID from sqlalchemy import Column @@ -19,39 +21,39 @@ class ElectionCompoundRelationship(Base): __tablename__ = 'election_compound_relationships' #: Identifies the relationship. - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The source election compound ID. - source_id: 'Column[str]' = Column( + source_id: Column[str] = Column( Text, ForeignKey('election_compounds.id', onupdate='CASCADE'), nullable=False ) #: The target election compound ID. - target_id: 'Column[str]' = Column( + target_id: Column[str] = Column( Text, ForeignKey('election_compounds.id', onupdate='CASCADE'), primary_key=True ) #: The source election compound. - source: 'relationship[ElectionCompound]' = relationship( + source: relationship[ElectionCompound] = relationship( 'ElectionCompound', foreign_keys=[source_id], back_populates='related_compounds' ) #: The target election compound. - target: 'relationship[ElectionCompound]' = relationship( + target: relationship[ElectionCompound] = relationship( 'ElectionCompound', foreign_keys=[target_id], back_populates='referencing_compounds' ) #: the type of relationship - type: 'Column[str | None]' = Column(Text, nullable=True) + type: Column[str | None] = Column(Text, nullable=True) diff --git a/src/onegov/election_day/models/file.py b/src/onegov/election_day/models/file.py index 9e1168f325..712b21b92c 100644 --- a/src/onegov/election_day/models/file.py +++ b/src/onegov/election_day/models/file.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.file import File diff --git a/src/onegov/election_day/models/mixins.py b/src/onegov/election_day/models/mixins.py index 2c56fd4d46..cb273c4276 100644 --- a/src/onegov/election_day/models/mixins.py +++ b/src/onegov/election_day/models/mixins.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.abstract import associated from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UTCDateTime @@ -42,7 +44,7 @@ class DomainOfInfluenceMixin: #: scope of the election or vote @declared_attr # type:ignore[no-redef] - def domain(cls) -> 'Column[DomainOfInfluence]': + def domain(cls) -> Column[DomainOfInfluence]: return Column( Enum( # type:ignore[arg-type] 'federation', @@ -71,7 +73,7 @@ def progress(self) -> tuple[int, int]: ... #: Status of the election or vote @declared_attr # type:ignore[no-redef] - def status(cls) -> 'Column[Status | None]': + def status(cls) -> Column[Status | None]: return Column( Enum( # type:ignore[arg-type] 'unknown', @@ -171,7 +173,7 @@ def get_short_title( or self.get_title(locale, default_locale) ) - def id_from_title(self, session: 'Session') -> str: + def id_from_title(self, session: Session) -> str: """ Returns a unique, user friendly id derived from the title. """ session_manager = self.session_manager @@ -188,7 +190,7 @@ def id_from_title(self, session: 'Session') -> str: id = increment_name(id) -def summarized_property(name: str) -> 'Column[int]': +def summarized_property(name: str) -> Column[int]: """ Adds an attribute as hybrid_property which returns the sum of the underlying results if called. @@ -216,7 +218,7 @@ def aggregate_results_expression(cls, attribute): def getter(self: Any) -> int: return self.aggregate_results(name) - def expression(cls: type[Any]) -> 'ColumnElement[int]': + def expression(cls: type[Any]) -> ColumnElement[int]: return cls.aggregate_results_expression(name) return hybrid_property(getter, expr=expression) # type:ignore @@ -229,17 +231,17 @@ class LastModifiedMixin(TimestampMixin): last_modified: Column[datetime | None] @declared_attr # type:ignore[no-redef] - def last_result_change(cls) -> 'Column[datetime | None]': + def last_result_change(cls) -> Column[datetime | None]: return Column(UTCDateTime) @hybrid_property # type:ignore[no-redef] - def last_modified(self) -> 'datetime | None': + def last_modified(self) -> datetime | None: changes = [self.last_change, self.last_result_change] changes = [change for change in changes if change] return max(changes) if changes else None @last_modified.expression # type:ignore[no-redef] - def last_modified(cls) -> 'ColumnElement[datetime | None]': + def last_modified(cls) -> ColumnElement[datetime | None]: return func.greatest(cls.last_change, cls.last_result_change) diff --git a/src/onegov/election_day/models/notification.py b/src/onegov/election_day/models/notification.py index 3e9f50bd0f..acf0ca2213 100644 --- a/src/onegov/election_day/models/notification.py +++ b/src/onegov/election_day/models/notification.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from email.headerregistry import Address from itertools import chain from onegov.core.custom import json @@ -43,7 +45,7 @@ class Notification(Base, TimestampMixin): #: subclasses of this class. See #: ``_. - type: 'Column[str]' = Column( + type: Column[str] = Column( Text, nullable=False, default=lambda: 'generic' @@ -55,33 +57,33 @@ class Notification(Base, TimestampMixin): } #: Identifies the notification - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The last update of the corresponding election/vote - last_modified: 'Column[datetime | None]' = Column( + last_modified: Column[datetime | None] = Column( UTCDateTime, nullable=True ) #: The corresponding election id - election_id: 'Column[str | None]' = Column( + election_id: Column[str | None] = Column( Text, ForeignKey(Election.id, onupdate='CASCADE', ondelete='CASCADE'), nullable=True ) #: The corresponding election - election: 'relationship[Election | None]' = relationship( + election: relationship[Election | None] = relationship( 'Election', back_populates='notifications' ) #: The corresponding election compound id - election_compound_id: 'Column[str | None]' = Column( + election_compound_id: Column[str | None] = Column( Text, ForeignKey( ElectionCompound.id, onupdate='CASCADE', ondelete='CASCADE' @@ -90,20 +92,20 @@ class Notification(Base, TimestampMixin): ) #: The corresponding election compound - election_compound: 'relationship[ElectionCompound | None]' = relationship( + election_compound: relationship[ElectionCompound | None] = relationship( 'ElectionCompound', back_populates='notifications' ) #: The corresponding vote id - vote_id: 'Column[str | None]' = Column( + vote_id: Column[str | None] = Column( Text, ForeignKey(Vote.id, onupdate='CASCADE', ondelete='CASCADE'), nullable=True ) #: The corresponding vote - vote: 'relationship[Vote | None]' = relationship( + vote: relationship[Vote | None] = relationship( 'Vote', back_populates='notifications' ) @@ -124,7 +126,7 @@ def update_from_model( def trigger( self, - request: 'ElectionDayRequest', + request: ElectionDayRequest, model: Election | ElectionCompound | Vote ) -> None: """ Trigger the custom actions. """ @@ -138,7 +140,7 @@ class WebhookNotification(Notification): def trigger( self, - request: 'ElectionDayRequest', + request: ElectionDayRequest, model: Election | ElectionCompound | Vote ) -> None: """ Posts the summary of the given vote or election to the webhook @@ -176,7 +178,7 @@ class EmailNotification(Notification): def set_locale( self, - request: 'ElectionDayRequest', + request: ElectionDayRequest, locale: str | None = None ) -> None: """ Changes the locale of the request. @@ -193,10 +195,10 @@ def set_locale( def send_emails( self, - request: 'ElectionDayRequest', - elections: 'Sequence[Election]', - election_compounds: 'Sequence[ElectionCompound]', - votes: 'Sequence[Vote]', + request: ElectionDayRequest, + elections: Sequence[Election], + election_compounds: Sequence[ElectionCompound], + votes: Sequence[Vote], subject: str | None = None ) -> None: """ Sends the results of the vote or election to all subscribers. @@ -222,7 +224,7 @@ def send_emails( # We use a generator function to submit the email batch since that # is significantly more memory efficient for large batches. - def email_iter() -> 'Iterator[EmailJsonDict]': + def email_iter() -> Iterator[EmailJsonDict]: for locale in request.app.locales: for group in groups: query = request.session.query(EmailSubscriber.address) @@ -292,7 +294,7 @@ def email_iter() -> 'Iterator[EmailJsonDict]': def trigger( self, - request: 'ElectionDayRequest', + request: ElectionDayRequest, model: Election | ElectionCompound | Vote ) -> None: """ Sends the results of the vote, election or election compound to @@ -320,11 +322,11 @@ class SmsNotification(Notification): def send_sms( self, - request: 'ElectionDayRequest', - elections: 'Sequence[Election]', - election_compounds: 'Sequence[ElectionCompound]', - votes: 'Sequence[Vote]', - content: 'TranslationString', + request: ElectionDayRequest, + elections: Sequence[Election], + election_compounds: Sequence[ElectionCompound], + votes: Sequence[Vote], + content: TranslationString, url: str | None = None ) -> None: """ Sends the given text to all subscribers. """ @@ -357,7 +359,7 @@ def send_sms( def trigger( self, - request: 'ElectionDayRequest', + request: ElectionDayRequest, model: Election | ElectionCompound | Vote ) -> None: """ Posts a link to the vote or election to all subscribers. diff --git a/src/onegov/election_day/models/party_result/__init__.py b/src/onegov/election_day/models/party_result/__init__.py index 36fcdfe3c6..2e636d42ad 100644 --- a/src/onegov/election_day/models/party_result/__init__.py +++ b/src/onegov/election_day/models/party_result/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models.party_result.party_panachage_result import \ PartyPanachageResult from onegov.election_day.models.party_result.party_result import PartyResult diff --git a/src/onegov/election_day/models/party_result/mixins.py b/src/onegov/election_day/models/party_result/mixins.py index 7dd28163ec..3af48d8655 100644 --- a/src/onegov/election_day/models/party_result/mixins.py +++ b/src/onegov/election_day/models/party_result/mixins.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.mixins import dict_property from onegov.core.orm.mixins import meta_property @@ -76,11 +78,11 @@ class HistoricalPartyResultsMixin: party_results: relationship[list[PartyResult]] @property - def relationships_for_historical_party_results(self) -> 'Query[Any]': + def relationships_for_historical_party_results(self) -> Query[Any]: raise NotImplementedError() @property - def historical_party_results(self) -> 'list[PartyResult]': + def historical_party_results(self) -> list[PartyResult]: """ Returns the party results while adding party results from the last legislative period, Requires that a related election or compound has been set with type "historical". diff --git a/src/onegov/election_day/models/party_result/party_panachage_result.py b/src/onegov/election_day/models/party_result/party_panachage_result.py index 69f672556b..4f848895a1 100644 --- a/src/onegov/election_day/models/party_result/party_panachage_result.py +++ b/src/onegov/election_day/models/party_result/party_panachage_result.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -21,27 +23,27 @@ class PartyPanachageResult(Base, TimestampMixin): __tablename__ = 'party_panachage_results' #: identifies the result - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the election id this result belongs to - election_id: 'Column[str | None]' = Column( + election_id: Column[str | None] = Column( Text, ForeignKey('elections.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=True ) #: the election this result belongs to - election: 'relationship[ProporzElection | None]' = relationship( + election: relationship[ProporzElection | None] = relationship( 'ProporzElection', back_populates='party_panachage_results' ) #: the election compound id this result belongs to - election_compound_id: 'Column[str | None]' = Column( + election_compound_id: Column[str | None] = Column( Text, ForeignKey( 'election_compounds.id', onupdate='CASCADE', ondelete='CASCADE' @@ -50,17 +52,17 @@ class PartyPanachageResult(Base, TimestampMixin): ) #: the election compound this result belongs to - election_compound: 'relationship[ElectionCompound | None]' = relationship( + election_compound: relationship[ElectionCompound | None] = relationship( 'ElectionCompound', back_populates='party_panachage_results' ) #: the party target this result belongs to, maps to party_id - target: 'Column[str]' = Column(Text, nullable=False) + target: Column[str] = Column(Text, nullable=False) #: the party source this result belongs to, maps to party_id; might also #: refer to the black list by being empty - source: 'Column[str]' = Column(Text, nullable=False) + source: Column[str] = Column(Text, nullable=False) # votes - votes: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0) + votes: Column[int] = Column(Integer, nullable=False, default=lambda: 0) diff --git a/src/onegov/election_day/models/party_result/party_result.py b/src/onegov/election_day/models/party_result/party_result.py index 1549e1f3be..29ea599cf2 100644 --- a/src/onegov/election_day/models/party_result/party_result.py +++ b/src/onegov/election_day/models/party_result/party_result.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm import translation_hybrid from onegov.core.orm.mixins import TimestampMixin @@ -27,27 +29,27 @@ class PartyResult(Base, TimestampMixin): __tablename__ = 'party_results' #: identifies the party result - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the election id this result belongs to - election_id: 'Column[str | None]' = Column( + election_id: Column[str | None] = Column( Text, ForeignKey('elections.id', onupdate='CASCADE', ondelete='CASCADE'), nullable=True ) #: the election this result belongs to - election: 'relationship[ProporzElection | None]' = relationship( + election: relationship[ProporzElection | None] = relationship( 'ProporzElection', back_populates='party_results' ) #: the election compound id this result belongs to - election_compound_id: 'Column[str | None]' = Column( + election_compound_id: Column[str | None] = Column( Text, ForeignKey( 'election_compounds.id', onupdate='CASCADE', ondelete='CASCADE' @@ -56,29 +58,29 @@ class PartyResult(Base, TimestampMixin): ) #: the election compound this result belongs to - election_compound: 'relationship[ElectionCompound | None]' = relationship( + election_compound: relationship[ElectionCompound | None] = relationship( 'ElectionCompound', back_populates='party_results' ) #: the domain of this result - domain: 'Column[str | None]' = Column(Text, nullable=True) + domain: Column[str | None] = Column(Text, nullable=True) #: the domain segment of this result - domain_segment: 'Column[str | None]' = Column(Text, nullable=True) + domain_segment: Column[str | None] = Column(Text, nullable=True) #: the number of mandates - number_of_mandates: 'Column[int]' = Column( + number_of_mandates: Column[int] = Column( Integer, nullable=False, default=lambda: 0 ) #: the number of votes - votes: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0) + votes: Column[int] = Column(Integer, nullable=False, default=lambda: 0) #: the number of total votes - total_votes: 'Column[int]' = Column( + total_votes: Column[int] = Column( Integer, nullable=False, default=lambda: 0 @@ -86,21 +88,21 @@ class PartyResult(Base, TimestampMixin): #: the number of total votes divided by the total number of mandates, #: used instead of total_votes by election compounds - voters_count: 'Column[Decimal | None]' = Column( + voters_count: Column[Decimal | None] = Column( Numeric(12, 2), nullable=True, default=lambda: 0 ) #: the voters count as percentage - voters_count_percentage: 'Column[Decimal | None]' = Column( + voters_count_percentage: Column[Decimal | None] = Column( Numeric(12, 2), nullable=True, default=lambda: 0 ) #: all translations of the party name - name_translations: 'Column[Mapping[str, str]]' = Column( + name_translations: Column[Mapping[str, str]] = Column( HSTORE, nullable=False ) @@ -110,7 +112,7 @@ class PartyResult(Base, TimestampMixin): name = translation_hybrid(name_translations) #: the year - year: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0) + year: Column[int] = Column(Integer, nullable=False, default=lambda: 0) #: the id of the party - party_id: 'Column[str]' = Column(Text, nullable=False) + party_id: Column[str] = Column(Text, nullable=False) diff --git a/src/onegov/election_day/models/principal.py b/src/onegov/election_day/models/principal.py index 2245facee3..84ad4cee1b 100644 --- a/src/onegov/election_day/models/principal.py +++ b/src/onegov/election_day/models/principal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import onegov.election_day from functools import cached_property @@ -73,8 +75,8 @@ def __init__( self, id_: str, domain: str, - domains_election: dict[str, 'TranslationString'], - domains_vote: dict[str, 'TranslationString'], + domains_election: dict[str, TranslationString], + domains_vote: dict[str, TranslationString], entities: dict[int, dict[int, dict[str, str]]], name: str | None = None, logo: str | None = None, @@ -102,7 +104,7 @@ def __init__( official_host: str | None = None, segmented_notifications: bool = False, private: bool = False, - **kwargs: 'Never' + **kwargs: Never ): assert all((id_, domain, domains_election, domains_vote, entities)) self.id = id_ @@ -146,7 +148,7 @@ def __init__( self.private = private @classmethod - def from_yaml(cls, yaml_source: '_ReadStream') -> 'Canton | Municipality': + def from_yaml(cls, yaml_source: _ReadStream) -> Canton | Municipality: kwargs = safe_load(yaml_source) assert 'canton' in kwargs or 'municipality' in kwargs if 'municipality' in kwargs: diff --git a/src/onegov/election_day/models/screen.py b/src/onegov/election_day/models/screen.py index b6d2fd633f..2d67b52362 100644 --- a/src/onegov/election_day/models/screen.py +++ b/src/onegov/election_day/models/screen.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from onegov.election_day.models.election import Election from onegov.election_day.models.election_compound import ElectionCompound @@ -55,46 +57,46 @@ class Screen(Base, ContentMixin, TimestampMixin): __tablename__ = 'election_day_screens' #: Identifies the screen - id: 'Column[int]' = Column(Integer, primary_key=True) + id: Column[int] = Column(Integer, primary_key=True) #: A unique number for the path - number: 'Column[int]' = Column(Integer, unique=True, nullable=False) + number: Column[int] = Column(Integer, unique=True, nullable=False) #: The vote - vote_id: 'Column[str | None]' = Column( + vote_id: Column[str | None] = Column( Text, ForeignKey(Vote.id, onupdate='CASCADE'), nullable=True ) - vote: 'relationship[Vote | None]' = relationship( + vote: relationship[Vote | None] = relationship( 'Vote', back_populates='screens' ) #: The election - election_id: 'Column[str | None]' = Column( + election_id: Column[str | None] = Column( Text, ForeignKey(Election.id, onupdate='CASCADE'), nullable=True ) - election: 'relationship[Election | None]' = relationship( + election: relationship[Election | None] = relationship( 'Election', back_populates='screens' ) #: The election compound - election_compound_id: 'Column[str | None]' = Column( + election_compound_id: Column[str | None] = Column( Text, ForeignKey(ElectionCompound.id, onupdate='CASCADE'), nullable=True ) - election_compound: 'relationship[ElectionCompound | None]' = relationship( + election_compound: relationship[ElectionCompound | None] = relationship( 'ElectionCompound', back_populates='screens' ) #: The domain of the election compound part. - domain: 'Column[str | None]' = Column(Text, nullable=True) + domain: Column[str | None] = Column(Text, nullable=True) #: The domain segment of the election compound part. - domain_segment: 'Column[str | None]' = Column(Text, nullable=True) + domain_segment: Column[str | None] = Column(Text, nullable=True) @property def election_compound_part(self) -> ElectionCompoundPart | None: @@ -105,22 +107,22 @@ def election_compound_part(self) -> ElectionCompoundPart | None: return None #: The title - description: 'Column[str | None]' = Column(Text, nullable=True) + description: Column[str | None] = Column(Text, nullable=True) #: The type - type: 'Column[str]' = Column(Text, nullable=False) + type: Column[str] = Column(Text, nullable=False) #: The content of the screen - structure: 'Column[str]' = Column(Text, nullable=False) + structure: Column[str] = Column(Text, nullable=False) #: Additional CSS - css: 'Column[str | None]' = Column(Text, nullable=True) + css: Column[str | None] = Column(Text, nullable=True) #: The group this screen belongs to, used for cycling - group: 'Column[str | None]' = Column(Text, nullable=True) + group: Column[str | None] = Column(Text, nullable=True) #: The duration this screen is presented if cycling - duration: 'Column[int | None]' = Column(Integer, nullable=True) + duration: Column[int | None] = Column(Integer, nullable=True) @property def model( @@ -141,7 +143,7 @@ def screen_type(self) -> ScreenType: return ScreenType(self.type) @property - def last_modified(self) -> 'datetime | None': + def last_modified(self) -> datetime | None: model = self.model assert model is not None changes = [self.last_change, model.last_change] @@ -149,7 +151,7 @@ def last_modified(self) -> 'datetime | None': return max(set_changes) if set_changes else None @property - def next(self) -> 'Screen | None': + def next(self) -> Screen | None: if self.group: session = object_session(self) query = session.query(Screen.number, Screen) diff --git a/src/onegov/election_day/models/subscriber.py b/src/onegov/election_day/models/subscriber.py index 7db130f3fb..c1037dfa9d 100644 --- a/src/onegov/election_day/models/subscriber.py +++ b/src/onegov/election_day/models/subscriber.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UTCDateTime @@ -23,7 +25,7 @@ class Subscriber(Base, TimestampMixin): #: subclasses of this class. See #: ``_. - type: 'Column[str]' = Column( + type: Column[str] = Column( Text, nullable=False, default=lambda: 'generic' @@ -35,7 +37,7 @@ class Subscriber(Base, TimestampMixin): } #: Identifies the subscriber - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 @@ -43,28 +45,28 @@ class Subscriber(Base, TimestampMixin): #: The address of the subscriber, e.g. the phone number or the email #: address. - address: 'Column[str]' = Column(Text, nullable=False) + address: Column[str] = Column(Text, nullable=False) #: The locale used by the subscriber - locale: 'Column[str]' = Column(Text, nullable=False) + locale: Column[str] = Column(Text, nullable=False) #: True, if the subscriber has been confirmed - active: 'Column[bool | None]' = Column(Boolean, nullable=True) + active: Column[bool | None] = Column(Boolean, nullable=True) #: The domain of the election compound part. - domain: 'Column[str | None]' = Column(Text, nullable=True) + domain: Column[str | None] = Column(Text, nullable=True) #: The domain segment of the election compound part. - domain_segment: 'Column[str | None]' = Column(Text, nullable=True) + domain_segment: Column[str | None] = Column(Text, nullable=True) #: When has this subscriber last been (explicitly) activated. - active_since: 'Column[datetime | None]' = Column( + active_since: Column[datetime | None] = Column( UTCDateTime, nullable=True ) #: When has this subscriber last been (explicitly) deactivated. - inactive_since: 'Column[datetime | None]' = Column( + inactive_since: Column[datetime | None] = Column( UTCDateTime, nullable=True ) diff --git a/src/onegov/election_day/models/upload_token.py b/src/onegov/election_day/models/upload_token.py index 514c491f77..b8d58f542e 100644 --- a/src/onegov/election_day/models/upload_token.py +++ b/src/onegov/election_day/models/upload_token.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -16,14 +18,14 @@ class UploadToken(Base, TimestampMixin): __tablename__ = 'upload_tokens' #: Identifies the token - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The token - token: 'Column[uuid.UUID]' = Column( + token: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] unique=True, default=uuid4, diff --git a/src/onegov/election_day/models/vote/__init__.py b/src/onegov/election_day/models/vote/__init__.py index 9dc44243e0..cf11933839 100644 --- a/src/onegov/election_day/models/vote/__init__.py +++ b/src/onegov/election_day/models/vote/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models.vote.ballot import Ballot from onegov.election_day.models.vote.ballot import BallotResult from onegov.election_day.models.vote.complex_vote import ComplexVote diff --git a/src/onegov/election_day/models/vote/ballot.py b/src/onegov/election_day/models/vote/ballot.py index 059428eefa..70ec999b00 100644 --- a/src/onegov/election_day/models/vote/ballot.py +++ b/src/onegov/election_day/models/vote/ballot.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm import translation_hybrid from onegov.core.orm.mixins import TimestampMixin @@ -66,14 +68,14 @@ class Ballot(Base, TimestampMixin, TitleTranslationsMixin, __tablename__ = 'ballots' #: identifies the ballot, maybe used in the url - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: external identifier - external_id: 'Column[str | None]' = Column(Text, nullable=True) + external_id: Column[str | None] = Column(Text, nullable=True) #: the type of the ballot, 'standard' for normal votes, 'counter-proposal' #: if there's an alternative to the standard ballot. And 'tie-breaker', @@ -81,7 +83,7 @@ class Ballot(Base, TimestampMixin, TitleTranslationsMixin, #: only relevant if both standard and counter proposal are accepted. #: If that's the case, the accepted tie breaker selects the standard, #: the rejected tie breaker selects the counter proposal. - type: 'Column[BallotType]' = Column( + type: Column[BallotType] = Column( Enum( # type:ignore[arg-type] 'proposal', 'counter-proposal', @@ -92,12 +94,12 @@ class Ballot(Base, TimestampMixin, TitleTranslationsMixin, ) #: identifies the vote this ballot result belongs to - vote_id: 'Column[str]' = Column( + vote_id: Column[str] = Column( Text, ForeignKey('votes.id', onupdate='CASCADE'), nullable=False ) #: all translations of the title - title_translations: 'Column[Mapping[str, str] | None]' = Column( + title_translations: Column[Mapping[str, str] | None] = Column( HSTORE, nullable=True ) @@ -107,20 +109,20 @@ class Ballot(Base, TimestampMixin, TitleTranslationsMixin, title = translation_hybrid(title_translations) #: a ballot contains n results - results: 'relationship[list[BallotResult]]' = relationship( + results: relationship[list[BallotResult]] = relationship( 'BallotResult', cascade='all, delete-orphan', back_populates='ballot', order_by='BallotResult.district, BallotResult.name', ) - vote: 'relationship[Vote]' = relationship( + vote: relationship[Vote] = relationship( 'Vote', back_populates='ballots', ) @property - def results_by_district(self) -> 'Query[ResultsByDistrictRow]': + def results_by_district(self) -> Query[ResultsByDistrictRow]: """ Returns the results aggregated by the distict. """ session = object_session(self) @@ -163,7 +165,7 @@ def counted(self) -> bool: return all(result.counted for result in self.results) @counted.expression # type:ignore[no-redef] - def counted(cls) -> 'ColumnElement[bool]': + def counted(cls) -> ColumnElement[bool]: expr = select([ func.coalesce(func.bool_and(BallotResult.counted), False) ]) @@ -220,7 +222,7 @@ def aggregate_results(self, attribute: str) -> int: def aggregate_results_expression( cls, attribute: str - ) -> 'ColumnElement[int]': + ) -> ColumnElement[int]: """ Gets the sum of the given attribute from the results, as SQL expression. diff --git a/src/onegov/election_day/models/vote/ballot_result.py b/src/onegov/election_day/models/vote/ballot_result.py index 309babd525..88ba611023 100644 --- a/src/onegov/election_day/models/vote/ballot_result.py +++ b/src/onegov/election_day/models/vote/ballot_result.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin from onegov.core.orm.types import UUID @@ -27,58 +29,58 @@ class BallotResult(Base, TimestampMixin, DerivedAttributesMixin, __tablename__ = 'ballot_results' #: identifies the result, may be used in the url - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The entity id (e.g. BFS number). - entity_id: 'Column[int]' = Column(Integer, nullable=False) + entity_id: Column[int] = Column(Integer, nullable=False) #: the name of the entity - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: the district this entity belongs to - district: 'Column[str | None]' = Column(Text, nullable=True) + district: Column[str | None] = Column(Text, nullable=True) #: True if the result has been counted and no changes will be made anymore. #: If the result is definite, all the values below must be specified. - counted: 'Column[bool]' = Column(Boolean, nullable=False) + counted: Column[bool] = Column(Boolean, nullable=False) #: number of yeas, in case of variants, the number of yeas for the first #: option of the tie breaker - yeas: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0) + yeas: Column[int] = Column(Integer, nullable=False, default=lambda: 0) #: number of nays, in case of variants, the number of nays for the first #: option of the tie breaker (so a yay for the second option) - nays: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0) + nays: Column[int] = Column(Integer, nullable=False, default=lambda: 0) #: number of empty votes - empty: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0) + empty: Column[int] = Column(Integer, nullable=False, default=lambda: 0) #: number of invalid votes - invalid: 'Column[int]' = Column(Integer, nullable=False, default=lambda: 0) + invalid: Column[int] = Column(Integer, nullable=False, default=lambda: 0) #: number of eligible voters - eligible_voters: 'Column[int]' = Column( + eligible_voters: Column[int] = Column( Integer, nullable=False, default=lambda: 0 ) #: number of expats - expats: 'Column[int | None]' = Column(Integer, nullable=True) + expats: Column[int | None] = Column(Integer, nullable=True) #: the id of the ballot this result belongs to - ballot_id: 'Column[uuid.UUID]' = Column( + ballot_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('ballots.id', ondelete='CASCADE'), nullable=False ) #: the ballot this result belongs to - ballot: 'relationship[Ballot]' = relationship( + ballot: relationship[Ballot] = relationship( 'Ballot', back_populates='results' ) diff --git a/src/onegov/election_day/models/vote/complex_vote.py b/src/onegov/election_day/models/vote/complex_vote.py index f003c14bbc..e38f20e9a4 100644 --- a/src/onegov/election_day/models/vote/complex_vote.py +++ b/src/onegov/election_day/models/vote/complex_vote.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models.vote.vote import Vote @@ -13,19 +15,19 @@ class ComplexVote(Vote): __mapper_args__ = {'polymorphic_identity': 'complex'} @property - def counter_proposal(self) -> 'Ballot': + def counter_proposal(self) -> Ballot: return self.ballot('counter-proposal') @property - def tie_breaker(self) -> 'Ballot': + def tie_breaker(self) -> Ballot: return self.ballot('tie-breaker') @staticmethod def get_answer( counted: bool, - proposal: 'Ballot | BallotResult | None', - counter_proposal: 'Ballot | BallotResult | None', - tie_breaker: 'Ballot | BallotResult | None' + proposal: Ballot | BallotResult | None, + counter_proposal: Ballot | BallotResult | None, + tie_breaker: Ballot | BallotResult | None ) -> str | None: if not (counted and proposal and counter_proposal and tie_breaker): diff --git a/src/onegov/election_day/models/vote/mixins.py b/src/onegov/election_day/models/vote/mixins.py index 1c948cb07d..3ad1fa8c86 100644 --- a/src/onegov/election_day/models/vote/mixins.py +++ b/src/onegov/election_day/models/vote/mixins.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sqlalchemy import case from sqlalchemy import cast from sqlalchemy import Float @@ -28,7 +30,7 @@ def yeas_percentage(self) -> float: return self.yeas / ((self.yeas + self.nays) or 1) * 100 @yeas_percentage.expression # type:ignore[no-redef] - def yeas_percentage(cls) -> 'ColumnElement[float]': + def yeas_percentage(cls) -> ColumnElement[float]: # coalesce will pick the first non-null result # nullif will return null if division by zero # => when all yeas and nays are zero the yeas percentage is 0% @@ -52,7 +54,7 @@ def accepted(self) -> bool: return self.yeas > self.nays if self.counted else None @accepted.expression # type:ignore[no-redef] - def accepted(cls) -> 'ColumnElement[bool]': + def accepted(cls) -> ColumnElement[bool]: return case({True: cls.yeas > cls.nays}, cls.counted) @@ -86,7 +88,7 @@ def turnout(self) -> float: ) @turnout.expression # type:ignore[no-redef] - def turnout(cls) -> 'ColumnElement[float]': + def turnout(cls) -> ColumnElement[float]: return case( [( cls.eligible_voters > 0, diff --git a/src/onegov/election_day/models/vote/vote.py b/src/onegov/election_day/models/vote/vote.py index a6dc46f902..66918cd5bc 100644 --- a/src/onegov/election_day/models/vote/vote.py +++ b/src/onegov/election_day/models/vote/vote.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base, observes from onegov.core.orm import translation_hybrid from onegov.core.orm.mixins import ContentMixin @@ -49,14 +51,14 @@ class Vote( __tablename__ = 'votes' @property - def polymorphic_base(self) -> type['Vote']: + def polymorphic_base(self) -> type[Vote]: return Vote #: the type of the item, this can be used to create custom polymorphic #: subclasses of this class. See #: ``_. - type: 'Column[str]' = Column(Text, nullable=False) + type: Column[str] = Column(Text, nullable=False) __mapper_args__ = { 'polymorphic_on': type, @@ -64,16 +66,16 @@ def polymorphic_base(self) -> type['Vote']: } #: identifies the vote, may be used in the url, generated from the title - id: 'Column[str]' = Column(Text, primary_key=True) + id: Column[str] = Column(Text, primary_key=True) #: external identifier - external_id: 'Column[str | None]' = Column(Text, nullable=True) + external_id: Column[str | None] = Column(Text, nullable=True) #: shortcode for cantons that use it - shortcode: 'Column[str | None]' = Column(Text, nullable=True) + shortcode: Column[str | None] = Column(Text, nullable=True) #: all translations of the title - title_translations: 'Column[Mapping[str, str]]' = Column( + title_translations: Column[Mapping[str, str]] = Column( HSTORE, nullable=False ) @@ -83,7 +85,7 @@ def polymorphic_base(self) -> type['Vote']: title = translation_hybrid(title_translations) #: all translations of the short title - short_title_translations: 'Column[Mapping[str, str] | None]' = Column( + short_title_translations: Column[Mapping[str, str] | None] = Column( HSTORE, nullable=True ) @@ -95,17 +97,17 @@ def polymorphic_base(self) -> type['Vote']: @observes('title_translations', 'short_title_translations') def title_observer( self, - title_translations: 'Mapping[str, str]', - short_title_translations: 'Mapping[str, str]' + title_translations: Mapping[str, str], + short_title_translations: Mapping[str, str] ) -> None: if not self.id: self.id = self.id_from_title(object_session(self)) #: identifies the date of the vote - date: 'Column[datetime.date]' = Column(Date, nullable=False) + date: Column[datetime.date] = Column(Date, nullable=False) #: a vote contains n ballots - ballots: 'relationship[list[Ballot]]' = relationship( + ballots: relationship[list[Ballot]] = relationship( 'Ballot', cascade='all, delete-orphan', order_by='Ballot.type', @@ -115,7 +117,7 @@ def title_observer( def ballot( self, - ballot_type: 'BallotType' + ballot_type: BallotType ) -> Ballot: """ Returns the given ballot if it exists, creates it if not. """ @@ -242,7 +244,7 @@ def aggregate_results(self, attribute: str) -> int: def aggregate_results_expression( cls, attribute: str - ) -> 'ColumnElement[int]': + ) -> ColumnElement[int]: """ Gets the sum of the given attribute from the results, as SQL expression. @@ -262,7 +264,7 @@ def aggregate_results_expression( last_modified: Column[datetime.datetime | None] @hybrid_property # type:ignore[no-redef] - def last_ballot_change(self) -> 'datetime.datetime | None': + def last_ballot_change(self) -> datetime.datetime | None: """ Returns last change of the vote, its ballots and any of its results. @@ -275,14 +277,14 @@ def last_ballot_change(self) -> 'datetime.datetime | None': return max(changes) if changes else None @last_ballot_change.expression # type:ignore[no-redef] - def last_ballot_change(cls) -> 'ColumnElement[datetime.datetime | None]': + def last_ballot_change(cls) -> ColumnElement[datetime.datetime | None]: expr = select([func.max(Ballot.last_change)]) expr = expr.where(Ballot.vote_id == cls.id) expr = expr.label('last_ballot_change') return expr @hybrid_property # type:ignore[no-redef] - def last_modified(self) -> 'datetime.datetime | None': + def last_modified(self) -> datetime.datetime | None: """ Returns last change of the vote, its ballots and any of its results. @@ -304,19 +306,19 @@ def last_modified(self) -> 'datetime.datetime | None': return max(changes) if changes else None @last_modified.expression # type:ignore[no-redef] - def last_modified(cls) -> 'ColumnElement[datetime.datetime | None]': + def last_modified(cls) -> ColumnElement[datetime.datetime | None]: return func.greatest( cls.last_change, cls.last_result_change, cls.last_ballot_change ) #: data source items linked to this vote - data_sources: 'relationship[list[DataSourceItem]]' = relationship( + data_sources: relationship[list[DataSourceItem]] = relationship( 'DataSourceItem', back_populates='vote' ) #: notifcations linked to this vote - notifications: 'relationship[AppenderQuery[Notification]]' + notifications: relationship[AppenderQuery[Notification]] notifications = relationship( # type:ignore[misc] 'onegov.election_day.models.notification.Notification', back_populates='vote', @@ -324,7 +326,7 @@ def last_modified(cls) -> 'ColumnElement[datetime.datetime | None]': ) #: screens linked to this vote - screens: 'relationship[AppenderQuery[Screen]]' = relationship( + screens: relationship[AppenderQuery[Screen]] = relationship( 'Screen', back_populates='vote', ) diff --git a/src/onegov/election_day/path.py b/src/onegov/election_day/path.py index e188ecf44b..1106d106c9 100644 --- a/src/onegov/election_day/path.py +++ b/src/onegov/election_day/path.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.converters import extended_date_converter from onegov.core.i18n import SiteLocale from onegov.election_day import ElectionDayApp @@ -43,7 +45,7 @@ model=Auth, path='/auth' ) -def get_auth(request: 'ElectionDayRequest', to: str = '/') -> Auth: +def get_auth(request: ElectionDayRequest, to: str = '/') -> Auth: return Auth.from_request(request, to) @@ -342,8 +344,8 @@ def get_archive_by_year( ) def get_archive_search( app: ElectionDayApp, - from_date: 'date | None' = None, - to_date: 'date | None' = None, + from_date: date | None = None, + to_date: date | None = None, answers: list[str] | None = None, item_type: str | None = None, domains: list[str] | None = None, @@ -368,7 +370,7 @@ def get_archive_search( path='/locale/{locale}' ) def get_locale( - request: 'ElectionDayRequest', + request: ElectionDayRequest, app: ElectionDayApp, locale: str ) -> SiteLocale | None: diff --git a/src/onegov/election_day/pdf.py b/src/onegov/election_day/pdf.py index 108b0d5419..ec7fbda37d 100644 --- a/src/onegov/election_day/pdf.py +++ b/src/onegov/election_day/pdf.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from babel.dates import format_date from babel.dates import format_time from copy import deepcopy @@ -24,7 +26,7 @@ def __init__( self, *args: Any, locale: str | None = None, - translations: dict[str, 'GNUTranslations'] | None = None, + translations: dict[str, GNUTranslations] | None = None, toc_levels: int = 3, created: str = '', logo: str | None = None, @@ -89,17 +91,17 @@ def translate(self, text: str) -> str: translated = translator.gettext(text) return text.interpolate(translated) - def h1(self, title: str, style: 'PropertySet | None' = None) -> None: + def h1(self, title: str, style: PropertySet | None = None) -> None: """ Translated H1. """ super().h1(self.translate(title), style=style) - def h2(self, title: str, style: 'PropertySet | None' = None) -> None: + def h2(self, title: str, style: PropertySet | None = None) -> None: """ Translated H2. """ super().h2(self.translate(title), style=style) - def h3(self, title: str, style: 'PropertySet | None' = None) -> None: + def h3(self, title: str, style: PropertySet | None = None) -> None: """ Translated H3. """ super().h3(self.translate(title), style=style) @@ -107,13 +109,13 @@ def h3(self, title: str, style: 'PropertySet | None' = None) -> None: def figcaption( self, text: str, - style: 'PropertySet | None' = None + style: PropertySet | None = None ) -> None: """ Translated Figcaption. """ super().figcaption(self.translate(text), style=style) - def dates_line(self, date: 'date', changed: 'datetime | None') -> None: + def dates_line(self, date: date, changed: datetime | None) -> None: """ Adds the given date and timespamp. """ self.table( diff --git a/src/onegov/election_day/request.py b/src/onegov/election_day/request.py index fe7f6e6446..ab5e19280f 100644 --- a/src/onegov/election_day/request.py +++ b/src/onegov/election_day/request.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.request import CoreRequest @@ -10,4 +12,4 @@ # in our election day app have the election day app available class ElectionDayRequest(CoreRequest): if TYPE_CHECKING: - app: 'ElectionDayApp' + app: ElectionDayApp diff --git a/src/onegov/election_day/screen_widgets/__init__.py b/src/onegov/election_day/screen_widgets/__init__.py index ac7376b817..47f73a9ac1 100644 --- a/src/onegov/election_day/screen_widgets/__init__.py +++ b/src/onegov/election_day/screen_widgets/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.screen_widgets.election_compound import ( ElectionCompoundCandidatesTableWidget, ElectionCompoundDistrictsMapWidget, diff --git a/src/onegov/election_day/screen_widgets/election.py b/src/onegov/election_day/screen_widgets/election.py index 9889e08dac..28d58ff33d 100644 --- a/src/onegov/election_day/screen_widgets/election.py +++ b/src/onegov/election_day/screen_widgets/election.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.screen_widgets.generic import ChartWidget from onegov.election_day.screen_widgets.generic import ModelBoundWidget @@ -34,7 +36,7 @@ class ElectionCandidatesTableWidget(ModelBoundWidget['Election']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model session = layout.request.session candidates = get_candidates_results(model, session).all() @@ -61,7 +63,7 @@ class ElectionCandidatesByEntityTableWidget(ModelBoundWidget['Election']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model candidates_by_entites = get_candidates_results_by_entity( model, sort_by_votes=True @@ -89,7 +91,7 @@ class ElectionListsTableWidget(ModelBoundWidget['ProporzElection']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model lists = get_list_results(model).all() return { @@ -115,7 +117,7 @@ class ElectionPartyStrengthsTableWidget(ModelBoundWidget['ProporzElection']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model party_years, parties = get_party_results(model) party_deltas, party_results = get_party_results_deltas( diff --git a/src/onegov/election_day/screen_widgets/election_compound.py b/src/onegov/election_day/screen_widgets/election_compound.py index 4d966fb241..388dac6f56 100644 --- a/src/onegov/election_day/screen_widgets/election_compound.py +++ b/src/onegov/election_day/screen_widgets/election_compound.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.screen_widgets.generic import ChartWidget from onegov.election_day.screen_widgets.generic import ModelBoundWidget @@ -35,7 +37,7 @@ class ElectionCompoundSeatAllocationTableWidget(ElectionCompoundWidget): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model party_years, parties = get_party_results(model) seat_allocations = get_party_results_seat_allocation( @@ -65,7 +67,7 @@ class ElectionCompoundCandidatesTableWidget(ElectionCompoundWidget): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model request = layout.request session = request.session @@ -102,7 +104,7 @@ class ElectionCompoundListGroupsTableWidget(ElectionCompoundWidget): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model groups = get_list_groups(model) return { @@ -128,7 +130,7 @@ class ElectionCompoundPartyStrengthsTableWidget(ElectionCompoundWidget): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model party_years, parties = get_party_results(model) party_deltas, party_results = get_party_results_deltas( @@ -159,7 +161,7 @@ class ElectionCompoundDistrictsTableWidget(ElectionCompoundWidget): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'election_compound': model, @@ -183,7 +185,7 @@ class ElectionCompoundDistrictsMapWidget(ElectionCompoundWidget): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'embed': False, @@ -208,7 +210,7 @@ class ElectionCompoundSuperregionsTableWidget(ElectionCompoundWidget): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model superregions = get_superregions(model, layout.app.principal) return { @@ -234,7 +236,7 @@ class ElectionCompoundSuperregionsMapWidget(ElectionCompoundWidget): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'embed': False, diff --git a/src/onegov/election_day/screen_widgets/generic.py b/src/onegov/election_day/screen_widgets/generic.py index c7113f2ab9..9649b15c1f 100644 --- a/src/onegov/election_day/screen_widgets/generic.py +++ b/src/onegov/election_day/screen_widgets/generic.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day import ElectionDayApp from onegov.qrcode import QrCode @@ -124,7 +126,7 @@ class PrincipalLogoWidget: """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: logo = layout.app.logo return {'logo': layout.request.link(logo) if logo else ''} @@ -150,7 +152,7 @@ def qr_code(url: str) -> str: QrCode(payload=url, encoding='base64').encoded_image.decode() ) - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: return {'qr_code': self.qr_code} @@ -159,7 +161,7 @@ class ModelBoundWidget(Generic[_E]): def __init__(self, model: _E | None = None) -> None: self.model = model - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: return { 'model': self.model or layout.model } @@ -228,7 +230,7 @@ class CountedEntitiesWidget(ModelBoundWidget['Entity']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model entities = ', '.join([ entity or layout.request.translate(_('Expats')) @@ -242,7 +244,7 @@ def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: class ChartWidget(ModelBoundWidget[_E]): - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: return { 'embed': False, 'model': self.model or layout.model diff --git a/src/onegov/election_day/screen_widgets/vote.py b/src/onegov/election_day/screen_widgets/vote.py index 4da3991f6e..d77ed88abd 100644 --- a/src/onegov/election_day/screen_widgets/vote.py +++ b/src/onegov/election_day/screen_widgets/vote.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.screen_widgets.generic import ModelBoundWidget @@ -62,7 +64,7 @@ class VoteProposalResultBarWidget(ModelBoundWidget['Vote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'proposal': model.proposal, @@ -87,7 +89,7 @@ class VoteCounterProposalResultBarWidget(ModelBoundWidget['ComplexVote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'counter_proposal': model.counter_proposal, @@ -112,7 +114,7 @@ class VoteTieBreakerResultBarWidget(ModelBoundWidget['ComplexVote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'tie_breaker': model.tie_breaker, @@ -138,7 +140,7 @@ class VoteProposalEntitiesTableWidget(ModelBoundWidget['Vote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model ballot = model.proposal results = sorted(ballot.results, key=lambda x: x.name) @@ -167,7 +169,7 @@ class VoteCounterProposalEntitiesTableWidget(ModelBoundWidget['ComplexVote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model ballot = model.counter_proposal results = sorted(ballot.results, key=lambda x: x.name) @@ -196,7 +198,7 @@ class VoteTieBreakerEntitiesTableWidget(ModelBoundWidget['ComplexVote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model ballot = model.tie_breaker results = sorted(ballot.results, key=lambda x: x.name) @@ -224,7 +226,7 @@ class VoteProposalEntitiesMap(ModelBoundWidget['Vote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'embed': False, @@ -250,7 +252,7 @@ class VoteCounterProposalEntitiesMap(ModelBoundWidget['ComplexVote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'embed': False, @@ -276,7 +278,7 @@ class VoteTieBreakerEntitiesMap(ModelBoundWidget['ComplexVote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'embed': False, @@ -302,7 +304,7 @@ class VoteProposalDistrictsMap(ModelBoundWidget['Vote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'embed': False, @@ -328,7 +330,7 @@ class VoteCounterProposalDistrictsMap(ModelBoundWidget['ComplexVote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'embed': False, @@ -354,7 +356,7 @@ class VoteTieBreakerDistrictsMap(ModelBoundWidget['ComplexVote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'embed': False, @@ -377,7 +379,7 @@ class VoteProposalTurnoutWidget(ModelBoundWidget['Vote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'embed': False, @@ -400,7 +402,7 @@ class VoteCounterProposalTurnoutWidget(ModelBoundWidget['ComplexVote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'embed': False, @@ -423,7 +425,7 @@ class VoteTieBreakerTurnoutWidget(ModelBoundWidget['ComplexVote']): """ usage = '' - def get_variables(self, layout: 'DefaultLayout') -> dict[str, Any]: + def get_variables(self, layout: DefaultLayout) -> dict[str, Any]: model = self.model or layout.model return { 'embed': False, diff --git a/src/onegov/election_day/security.py b/src/onegov/election_day/security.py index 4ddd572216..8225071702 100644 --- a/src/onegov/election_day/security.py +++ b/src/onegov/election_day/security.py @@ -1,3 +1,4 @@ +from __future__ import annotations from onegov.core.security import Private from onegov.core.security import Public @@ -40,7 +41,7 @@ def has_permission_maybe_public_not_logged_in( ) def has_permission_maybe_public_logged_in( app: ElectionDayApp, - identity: 'Identity', + identity: Identity, model: object, permission: MaybePublic ) -> bool: diff --git a/src/onegov/election_day/static/mapdata/2025/351.json b/src/onegov/election_day/static/mapdata/2025/351.json new file mode 100644 index 0000000000..721eb0da56 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/351.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":1,"properties":{"id":1,"name":"Innere Stadt"},"arcs":[[-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]]},{"type":"Polygon","id":2,"properties":{"id":2,"name":"Länggasse/Felsenau"},"arcs":[[-11,5,-12,3,-13,-14,-15,-16,-17]]},{"type":"Polygon","id":3,"properties":{"id":3,"name":"Mattenhof/Weissenbühl"},"arcs":[[10,-18,-19,-20,-21,-22,0,-23,8,-24,6]]},{"type":"Polygon","id":4,"properties":{"id":4,"name":"Kirchenfeld/Schosshalde"},"arcs":[[-25,1,21,-26,19,-27]]},{"type":"Polygon","id":5,"properties":{"id":5,"name":"Breitenrain/Lorraine"},"arcs":[[-28,12,2,24]]},{"type":"Polygon","id":6,"properties":{"id":6,"name":"Bümpliz/Bethlehem"},"arcs":[[-29,17,16,-30,14]]}]}},"arcs":[[[7643,-3756],[-5,-27],[-3,-11],[-1,-6],[-2,-16]],[[8156,-4255],[2,57],[-2,71],[-2,81],[-4,75],[-6,51],[-21,49],[-19,33],[-17,18],[-70,76],[-31,33],[-32,13],[-243,-61],[-58,2],[-10,1]],[[7394,-4756],[84,171],[24,43],[37,51],[40,41],[99,89],[24,15],[25,11],[25,9],[26,5],[26,1],[25,-4],[26,-7],[108,-38],[33,-10],[40,-2],[33,5],[23,6],[22,10],[18,24],[13,27],[10,41],[1,13]],[[7381,-4734],[13,-22]],[[7350,-4678],[31,-56]],[[7105,-4092],[-19,-132],[1,-1],[4,-3],[4,-3],[4,-3],[4,-4],[4,-4],[5,-5],[5,-6],[13,41],[2,-1],[2,-2],[2,-2],[1,-2],[2,-2],[5,-6],[3,-4],[3,-4],[35,-53],[3,-5],[3,-5],[3,-5],[3,-6],[3,-5],[3,-6],[3,-6],[3,-6],[2,-6],[2,-5],[5,-16],[2,-6],[2,-7],[3,-10],[2,-11],[-17,-20],[2,-12],[3,-12],[2,-8],[1,-7],[5,-30],[1,-8],[1,-7],[1,-8],[34,3],[5,-30],[25,-45],[47,-85],[11,-20],[1,2],[1,2]],[[7444,-3805],[-3,-0],[-3,-1],[-2,-1],[-2,-2],[-3,-2],[-3,-2],[0,1],[-1,-2],[-1,-4],[-8,4],[-9,3],[2,15],[-8,25],[-14,7],[-13,-15],[-2,-10],[0,-5],[-31,17],[-7,-7],[-7,3],[-22,10],[-2,1],[2,6],[1,7],[-40,152],[0,1],[0,1],[-1,-0],[-1,1],[-1,-0],[-1,-0],[-1,-0],[-1,-0],[-1,-1],[-1,-2],[0,-1],[-40,-101],[-11,-86],[-13,6],[-36,17],[-46,23],[-2,1],[-2,1],[-1,2],[-2,2],[-1,3],[-1,2],[-1,3],[-1,3],[-8,-37],[5,-20],[1,-5],[0,1],[4,-16],[1,-6],[0,-1],[0,-1],[2,-15],[0,-1],[1,-0],[0,-1],[3,-21],[2,-16],[4,-31],[2,-14],[2,-14],[-1,-3],[0,-1],[0,-1],[1,-0],[0,-1],[0,-1],[-1,-1],[0,-1],[-1,-0],[0,-1],[-1,-0],[0,1],[-1,1],[-1,-4],[1,-39],[-4,-29],[-3,-19],[3,-1],[-9,-64]],[[7453,-3805],[-3,-0],[-3,-0],[-3,-0]],[[7602,-3837],[0,2],[-1,1],[0,1],[-1,1],[0,1],[-1,-0],[-1,-0],[-1,-0],[-1,-0],[-1,-1],[0,-1],[-12,4],[-2,1],[-1,1],[-2,1],[-2,1],[-1,-0],[-2,-0],[-2,-0],[-3,-0],[-7,-1],[-7,-2],[0,-2],[-3,-0],[-27,1],[0,4],[-5,1],[-3,1],[-19,-0],[0,-4],[-20,-0],[0,2],[-1,1],[-2,3],[-2,3],[-3,3],[-3,2],[0,1],[-2,1],[-2,2],[-3,1],[-2,1],[-2,1],[-2,1]],[[7632,-3816],[-29,-20],[-1,-1]],[[7105,-4092],[-18,9],[-60,28],[-42,21],[0,7],[-1,5],[-4,1],[-5,-0],[-4,1],[-5,1],[-11,3],[-5,2],[-4,1],[-5,-0],[-5,1],[-4,-0],[-5,-0],[-6,-0],[-3,-0],[-3,1],[-3,-0],[0,18],[-126,-13],[-3,-1],[-4,-1],[-4,-1],[-2,-2],[-3,-1],[-3,-2],[-3,-2],[-35,-33],[-28,-27],[-17,-18],[-8,-9],[-6,-8],[-9,-13],[-9,-14],[-1,3],[-4,-7],[-10,-16],[-27,-44],[-20,-32],[-6,-9],[-5,-9],[-2,-3],[-3,-6],[-6,-8],[-9,-15],[-8,-14],[-4,-4],[-9,-14],[-10,-14],[-9,-12],[-21,-31],[-10,-15],[-7,-9],[-10,-17],[-4,-7],[-3,-5],[-7,-13],[-7,-13],[-3,-4],[-5,-9],[-8,-13],[-8,-14],[-13,-20],[-7,-11],[-9,-13],[-2,-3],[-2,-4],[-1,-3],[-2,-2],[-2,-2],[-1,-3],[-4,-4],[-5,-6],[-5,-5],[-8,-8],[-4,3],[-12,-15],[-2,1],[-1,1],[-2,1],[-2,-0],[-1,-0],[-2,-0],[-2,-0],[-2,-1],[-2,-1],[-8,-7],[-4,-3],[-3,-3],[-4,-4],[-3,-3],[-3,-4],[-4,-4],[-5,-1],[-6,-2],[-6,-1],[-19,-39],[7,-0],[7,1],[-4,-8],[-6,-12],[-1,-2],[0,-2],[-1,-3],[0,-3],[-1,-2],[0,-3],[0,-3],[-11,-35],[-1,1],[-1,1],[-1,-0],[-2,-0],[-1,-1],[-2,-1],[-2,-1],[-1,-2],[-2,-2],[-2,-2],[-2,-3],[-1,2],[-11,23],[-9,2],[0,2],[0,1],[-1,2],[0,1],[-1,1],[-2,2],[-1,1],[-2,2],[-2,1],[-2,1],[-3,1],[-4,1],[-4,2],[-4,2],[-4,2],[-5,3],[-4,3],[-4,3],[-3,3],[-3,3],[-2,3],[-2,2],[-3,3],[-2,3],[-3,2],[-3,3],[-7,4],[-12,10],[-12,12],[-13,12],[-12,14],[-11,15],[-11,15],[-10,16],[-11,17],[-21,36],[-9,16],[-10,14],[-11,14],[-11,12],[-11,12],[-11,10],[-12,9],[-12,8],[-7,5],[-15,9],[-32,18],[-26,15],[-5,2],[-31,18],[-91,52],[-33,18],[-2,-0],[-6,-0],[-67,-4],[-8,-0],[-26,-1],[-7,-0],[-1,29]],[[7381,-4734],[-1,2],[-30,54]],[[8580,-7934],[-4,83],[-26,108],[-102,204],[-56,178],[-96,152],[-81,70],[-89,-12],[-198,-179],[-71,-9],[-50,23],[-53,33],[-50,47],[-43,73],[-28,67],[-38,143],[-25,96],[-35,139],[-15,70],[-21,76],[-29,91],[-22,71],[-23,91],[-18,100],[-22,191],[-63,518],[-9,75],[-16,123],[-4,46],[-2,47],[0,47],[3,47],[5,47],[6,46],[9,45],[10,44],[18,62],[22,59],[30,66]],[[4496,-6658],[449,-74],[311,-317],[409,70],[191,-167],[189,-165],[65,-19],[55,-15],[5,-3],[143,-35],[68,-69],[174,-175],[97,-72],[74,8],[73,47],[78,102],[64,190],[10,93],[27,226],[18,53],[13,37],[56,35],[68,-35],[36,-68],[38,-156],[9,-452],[3,-173],[15,-127],[25,-93],[42,-106],[50,-27],[51,22],[76,150],[44,135],[66,-14],[67,-105],[33,-192],[-18,-185],[-49,-98],[-58,-0],[-123,133],[-78,-59],[-45,-77],[-15,-110],[23,-96],[64,-117],[95,-166],[84,-261],[25,-151],[7,-217],[18,-158],[43,-163],[108,-125],[39,4],[37,62],[9,89],[18,720],[2,51],[7,57],[11,78],[10,79],[9,79],[46,460],[9,56],[18,49],[24,37],[26,19],[38,14],[7,3],[332,105],[93,-2],[35,16],[27,40],[14,49]],[[4771,-5172],[-5,-57],[-6,-37],[-1,-26],[-5,-34],[-8,-34],[-4,-30],[-8,-43],[-2,-14],[-3,-14],[-3,-15],[-3,-14],[-3,-14],[-3,-13],[-4,-14],[-3,-14],[-4,-13],[-6,-20],[-6,-19],[-6,-19],[-6,-20],[-6,-19],[-6,-19],[-13,-38],[-12,-38],[-5,-7],[-12,-32],[-13,-30],[-14,-30],[-14,-29],[-15,-31],[-27,-68],[-12,-33],[-8,-29],[-18,-44],[-6,-8],[-14,-42],[-7,-20],[-8,-21],[-9,-19],[0,-2],[-1,-2],[0,-2],[-1,-3],[0,-2],[0,-2],[1,-3],[0,-2],[1,-2],[0,-2],[5,-11],[75,-191],[5,-11],[6,-10],[5,-7],[6,-6],[-1,-25],[-10,-10],[-9,-12],[-8,-14],[-6,-12],[-5,-13],[-3,-17],[-3,-22],[-1,-9],[-4,-9],[4,-5],[-5,-8],[0,-6],[-18,-45]],[[4776,-5126],[-5,-46]],[[5592,-4253],[-20,-1],[-1,-5],[0,-5],[-3,-2],[-3,-3],[-2,-2],[-3,-3],[-3,-3],[-2,-3],[-2,-4],[-3,-3],[-9,-17],[0,11],[-26,-2],[-4,8],[-32,-2],[-51,-9],[-68,-13],[-68,-13],[-19,12],[-3,-5],[-47,-78],[9,-34],[-34,-34],[-5,18],[-70,-117],[-92,-130],[-47,37],[-33,26],[-40,31],[-41,32],[-8,-24],[-2,-4],[-1,-5],[-2,-6],[-1,-5],[-1,-5],[-1,-6],[-26,-72],[-2,-2],[-2,-2],[-1,-3],[-2,-3],[-1,-3],[-1,-3],[-13,-35],[-7,-31],[-12,-38],[-10,-106],[-1,-76],[8,-2],[8,-1],[-4,-16],[-3,-16],[-6,-40],[2,-2],[-2,-16],[-2,-19],[-1,-19]],[[4634,-1600],[21,-40],[20,-39],[45,-57],[46,-19],[7,-3],[10,-4],[25,-10],[19,-7],[24,8],[-6,-30],[-5,-26],[-9,-47],[19,-10],[19,-10],[15,-9],[15,-12],[16,-12],[16,-14],[11,-9],[10,-10],[11,-11],[18,-23],[16,-23],[15,-24],[7,-12],[7,-14],[14,-27],[13,-28],[16,-42],[9,-25],[7,-21],[12,-49],[14,-49],[1,1],[1,-2],[-1,-1],[19,-70],[10,-33],[10,-32],[12,-30],[15,-34],[10,-18],[12,-19],[16,-21],[10,-18],[7,-15],[9,-15],[13,-18],[14,-16],[21,-25],[12,-11],[15,-13],[15,-11],[14,-10],[18,-13],[12,-9],[24,-20],[-13,-49],[13,-10],[19,-12],[23,-27],[23,-34],[23,-49],[32,-75],[1,-8],[-3,-28],[0,-15],[6,-30],[4,-14],[5,-2],[6,-7],[5,-13],[3,-14],[1,-10],[-2,-3],[24,-31],[1,-12],[-1,-2],[-2,-1],[-1,-1],[-2,-1],[-40,-10],[-11,-3],[-11,-3],[-6,-1],[-6,-1],[-6,-1],[-6,-0],[-6,-0],[0,-11],[6,-50],[-4,-14],[0,-3],[-18,19],[-10,-38],[0,-3],[-7,-12],[15,-26],[4,-7],[0,-1],[22,-40],[11,-23],[7,-16],[10,-16],[14,-19],[16,-34],[9,-11],[3,-6],[6,-11],[24,-43],[15,-27],[1,-11],[1,-10],[1,-10],[2,-10],[1,-10],[2,-10],[2,-9],[2,-8],[2,-9],[2,-8],[-5,-4],[-9,-44],[0,-4],[14,-65],[-15,-0],[-21,-5],[-1,-173],[0,-5],[22,1],[6,-0],[0,-3],[0,-3],[2,-107],[-14,-1],[0,-44],[1,-81]],[[7859,-1958],[-7,34],[-1,3],[-6,32],[-2,8],[-11,54],[-9,-13],[-5,-8],[-7,-0],[-16,-0],[-2,-4],[-4,-5],[-7,8],[-11,17],[-13,10],[0,2],[-4,-1],[-6,-1],[-2,26],[-4,-1],[-4,-1],[-19,-6],[-3,-1],[-8,2],[-4,1],[-14,-0],[-6,-0],[-3,-0],[-13,43],[1,-0],[-3,13],[-7,24],[-7,22],[-4,17],[-5,17],[-4,13],[-4,13],[-5,19],[-3,11],[-3,4],[-5,10],[-11,-29],[-3,-6],[-2,-6],[-3,-6],[-3,-6],[-3,-5],[-3,-6],[1,-0],[-4,-6],[-4,-6],[-3,-6],[-4,-5],[-4,-6],[-4,-5],[-22,-25],[-3,-4],[-4,-3],[-3,-3],[-4,-3],[-7,-5],[-3,1],[-6,1],[-10,-7],[-2,-2],[1,-3],[-2,-3],[-17,-18],[-13,-19],[-24,-33],[-25,-30],[-34,-36],[-34,-32],[-41,-44],[-1,-2],[-23,-25],[-14,-20],[-14,-21],[-12,-18],[-2,3],[-2,-4],[-9,-15],[-16,-29],[-22,-26],[-17,-9],[-14,-8],[-20,-20],[-15,-15],[-26,-27],[-17,-10],[-24,-7],[-21,-11],[-26,-6],[-9,-2],[-3,8],[-4,12],[-15,43],[-17,49],[-9,27],[-21,73],[-12,47],[20,31],[17,28],[7,11],[18,28],[2,4],[42,65],[22,32],[17,23],[25,37],[16,21],[11,15],[-2,9],[-2,24],[-2,5],[0,2],[-4,-2],[-5,-2],[-14,-5],[-6,-2],[-14,-4],[-28,-8],[-30,-9],[-9,-3],[-16,-4],[-7,-2],[-4,-1],[-17,-6],[-6,-1],[-1,-1],[-31,-9],[-40,-11],[-6,-12],[-5,-4],[-1,2],[-1,1],[-1,2],[-1,1],[-1,1],[-2,-0],[-2,1],[-6,1],[-3,-1],[-3,-1],[-2,-1],[-3,-1],[-3,-1],[-2,-2],[-3,-2],[-2,-2],[-3,-3],[-3,-3],[-9,-12],[-2,-2],[-2,-2],[-1,-2],[-2,-1],[-3,-4],[-2,-1],[-1,-1],[-1,-1],[-2,-1],[-1,-1],[-6,-4],[-1,-0],[0,-1],[-1,-0],[0,-1],[-5,-8],[8,-25],[0,-2],[1,-1],[0,-2],[0,-1],[0,-2],[-1,-2],[0,-1],[0,-1],[-1,-1],[-1,-1],[-5,-8],[-6,-7],[-6,-8],[-17,-26],[-9,-14],[-10,-13],[-1,-1],[-10,-11],[-5,-5],[-10,-9],[-14,-13],[-5,-3],[-9,-14],[-17,-12],[-15,-7],[-12,-8],[-16,-11],[-4,-1],[-10,-3],[-15,-13],[-16,-18],[-16,-25],[-44,-66],[-27,-50],[-10,-23],[-2,-4],[-2,7],[-10,34],[-11,34],[-3,11],[0,2],[-8,26],[-11,-15],[-8,-11],[-8,-11],[-10,-15],[-8,30],[-2,7],[-8,-8],[-13,-13],[-19,-18],[-9,-9],[-11,-13],[-2,-2],[-19,-29],[-12,28],[-5,13],[-4,10],[-4,10],[0,-1],[-2,-2],[-26,-47],[-28,-49],[-2,-2],[-1,-3],[-48,-85],[-69,-120],[-2,-0],[-2,-0],[-1,-0],[-23,-2],[-1,-0],[-3,-3],[-33,-25],[-14,-11],[-2,-1],[-1,-0],[-4,-2],[-4,-1],[-15,-6],[-12,-4],[-4,-1],[-1,-1],[-2,-1],[-10,-3],[-5,-2],[-9,-3],[1,16],[1,9],[2,17],[2,16],[-9,4],[3,20],[-1,39],[-1,14],[-1,13],[-4,23],[-2,16],[-2,16],[-3,23],[-2,25],[-2,31],[-6,52],[0,4],[-3,57],[-4,-0],[-4,49],[-2,21],[-1,6],[-2,13],[-5,25],[-3,23],[-4,37],[-11,27],[1,9],[8,47],[2,13],[0,2],[2,14],[2,14],[2,15],[2,14],[1,12],[1,3],[-5,2],[-15,6],[-11,5],[-4,1],[-1,1],[-20,9],[-14,6],[-4,1],[-12,5],[-8,4],[-5,2],[-13,5],[4,39],[-13,6],[-21,9],[-6,2],[-1,-7],[-4,3],[0,6],[-13,6],[-18,8],[-14,6],[-4,-41],[-1,-0],[-10,4],[-9,3],[-10,1],[-8,1],[-1,-0],[-14,-0],[-21,-9],[-3,-2],[-14,18],[-17,21],[0,1],[-2,1],[-9,18],[-1,2],[-14,23],[0,42],[0,26],[0,49],[0,47],[0,3],[0,23],[0,8],[0,20],[0,10],[0,8],[0,11],[0,15],[0,8],[0,34],[3,8],[12,28],[4,22],[2,36],[0,10],[-3,29],[-2,12],[-8,54],[-1,21],[2,32],[3,8],[8,23],[2,6],[5,14],[5,14],[3,9],[6,20],[2,9],[2,3],[3,7],[0,1],[-3,4],[-12,16],[-4,5],[-10,12],[-6,7],[-13,15],[-3,4],[-10,11],[-9,10],[-1,1],[-11,10],[-18,19],[-16,16],[-18,11],[-19,10],[-17,8],[-7,3],[-13,5],[-25,9],[-8,-2],[-5,-1],[-22,-3],[-4,1],[-9,2],[-9,5],[-15,10],[-8,12],[-18,45],[-24,58],[-6,30],[-8,33],[-5,27],[-1,29],[9,24],[8,14],[10,9],[0,25],[4,55],[2,27],[0,22],[-3,25],[-27,-52],[-25,-55],[-23,-32],[-17,-63],[-13,-23],[-32,-63],[-26,-60],[-26,-52],[-21,-49],[-28,-60],[-30,-79],[-38,-29],[-31,-37],[-20,-23],[-23,-29],[-24,-31],[-27,-54],[-19,-41],[-15,-39],[-14,-26],[-26,-48],[-15,-27],[-10,-17],[-12,-20],[-14,-21],[-10,-17],[-9,-18],[-14,-28],[-12,-30],[-4,-10],[-13,-22],[-15,-21],[-8,-13],[-7,-15],[-8,-17],[-15,-31],[-20,-51]],[[7482,-2972],[-14,173],[-4,53],[-4,53],[-3,52],[-1,53],[0,54],[3,53],[5,52],[6,49],[9,51],[10,50],[11,48],[16,43],[17,40],[16,33],[21,34],[22,30],[11,14],[18,17],[21,16],[50,27],[38,17],[44,11],[43,2],[42,-11]],[[7511,-3347],[-15,188],[-14,187]],[[7643,-3756],[-22,13],[-20,18],[-24,18],[-20,26],[-14,48],[-14,45],[-3,53],[-15,188]],[[7602,-3837],[30,21]],[[7444,-3805],[3,-0],[2,-0],[3,-0],[1,-0]],[[8156,-4255],[17,-6],[4,-1],[5,-8],[1,2],[0,-1],[3,-7],[1,-1],[1,-1],[1,-0],[1,-0],[1,-0],[0,1],[4,3],[5,7],[1,7],[0,6],[0,4],[4,10],[-1,46],[0,6],[0,19],[0,7],[1,3],[0,4],[1,3],[1,3],[1,3],[1,3],[1,2],[1,-2],[1,2],[2,2],[1,2],[1,1],[4,1],[-1,4],[4,1],[5,1],[12,3],[3,-2],[2,-2],[5,-6],[1,-3],[2,-3],[1,-4],[1,-3],[1,-4],[1,-4],[1,-4],[1,-4],[0,-4],[1,-4],[0,-4],[0,-4],[0,-5],[0,-4],[0,-4],[0,-4],[-20,-177],[-1,-9],[-1,-9],[-2,-9],[-1,-9],[-2,-9],[-2,-9],[-2,-9],[-2,-9],[-2,-8],[-2,-8],[-43,-146],[-1,-7],[-2,-6],[-1,-8],[-1,-7],[-1,-7],[-1,-7],[0,-8],[-1,-7],[0,-8],[0,-7],[1,-8],[0,-7],[1,-8],[1,-7],[1,-7],[1,-7],[1,-7],[2,-7],[13,-49],[1,-0],[12,-39],[23,-84],[3,-12],[2,-10],[5,-16],[4,-17],[5,-16],[5,-18],[1,-6],[3,-9],[44,-164],[18,-68],[11,-39],[16,-60],[40,-148],[6,-24],[2,-0],[10,-35],[4,-15],[13,-49],[-3,2],[18,-67],[62,-228],[3,3],[11,-44],[1,1],[44,-162],[40,-150],[1,1],[9,-33],[-1,-8],[2,-6],[2,-6],[2,-6],[3,-9],[3,-8],[3,-6],[2,-5],[3,-6],[30,-122],[0,-2],[0,-2],[0,-3],[1,-2],[24,-88],[6,-22],[-2,-1],[3,-9],[3,-12],[3,-10],[9,-33],[2,-10],[4,-14],[2,-8],[21,-75],[2,-10],[3,-10],[1,-6],[1,-6],[-1,-1]],[[7482,-2972],[29,-375]],[[8738,-6800],[43,-164],[14,-14],[53,-44],[52,-62],[9,-7],[5,-5],[10,-4],[50,-5],[1,-0],[29,-4],[17,-3],[6,6],[6,-2],[11,-3],[18,-10],[2,-1],[1,-7],[3,-13],[1,-22],[0,-25],[4,-24],[2,-11],[2,-11],[18,-36],[8,-11],[14,-11],[6,-9],[5,-17],[6,-12],[24,-3],[12,1],[12,2],[18,1],[9,-3],[9,-7],[38,-41],[48,18],[48,17],[45,41],[12,17],[11,17],[17,48],[13,36],[13,68],[13,87],[0,1],[4,75],[3,80],[24,2],[22,5],[-12,78],[-13,78],[36,45],[-30,84],[2,28],[-4,36],[-8,28],[7,42],[2,10],[2,11],[0,2],[2,10],[-18,14],[-17,12],[-18,12],[-19,10],[-18,10],[-18,8],[-19,8],[-18,6],[-19,6],[-20,7],[-1,-0],[-20,6],[-16,7],[-14,6],[-6,4],[-7,5],[-14,10],[-14,14],[-18,17],[-10,10],[-6,7],[-26,28],[-1,5],[-3,11],[-20,24],[-4,4],[10,19],[7,17],[-5,32],[22,42],[12,30],[12,34],[8,26],[1,6],[7,27],[4,19],[4,17],[3,15],[6,29],[-24,26],[-15,16],[-1,-1],[-2,-1],[3,10],[5,18],[4,18],[-5,5],[-1,-1],[0,-1],[-1,-1],[0,-1],[-1,-0],[-1,-0],[-1,-0],[0,1],[-1,-0],[0,1],[-13,24],[5,10],[3,7],[3,7],[4,8],[0,28],[-1,4],[-2,35],[0,4],[0,1],[-5,33],[-1,5],[-3,2],[-5,3],[-12,7],[4,33],[3,21],[0,4],[2,13],[1,5],[3,29],[1,6],[3,26],[2,18],[2,14],[4,33],[0,1],[3,23],[0,3],[1,6],[5,18],[1,2],[5,17],[1,5],[1,18],[1,12],[-4,16],[-3,12],[-1,1],[0,3],[-2,4],[-7,22],[-16,22],[-1,1],[-13,9],[-9,6],[0,1],[-3,31],[-2,1],[-7,2],[-5,1],[-2,1],[-10,3],[-5,1],[-3,1],[-10,2],[-6,2],[-11,3],[-10,3],[-6,2],[-7,2],[6,27],[4,17],[4,12],[-7,7],[-3,19],[-3,14],[0,3],[0,2],[0,3],[0,3],[4,42],[0,1],[1,1],[0,1],[0,1],[1,-0],[0,1],[1,-0],[1,-0],[1,6],[2,13],[1,7],[3,16],[40,-9],[5,7],[22,32],[12,14],[5,6],[15,26],[8,3],[8,14],[13,22],[10,17],[0,5],[23,42],[26,46],[2,-1],[29,59],[22,53],[9,21],[12,37],[10,32],[15,27],[5,15],[8,39],[7,22],[13,15],[9,20],[11,17],[-1,8],[-20,177],[-13,121],[-2,16],[24,18],[1,1],[3,2],[1,1],[-11,116],[-2,36],[-1,96],[-3,33],[-8,50],[2,3],[3,2],[73,77],[13,-67],[2,11],[19,46],[4,16],[14,36],[4,7],[7,-0],[11,10],[5,4],[17,17],[18,13],[7,4],[8,2],[21,12],[13,16],[4,5],[8,13],[11,24],[9,25],[25,66],[13,18],[27,46],[27,65],[1,-3],[33,-98],[8,25],[10,26],[21,46],[13,34],[7,19],[8,17],[15,33],[13,25],[22,42],[3,6],[15,28],[13,21],[7,13],[14,23],[16,26],[20,31],[-1,7],[-8,41],[-6,27],[-1,7],[-14,58],[-15,-14],[-14,-14],[-11,45],[-3,11],[-17,64],[-11,43],[-23,-63],[-3,-5],[-2,-6],[-2,-5],[-3,-5],[-3,-4],[-3,-4],[-3,-4],[-3,-4],[-3,-3],[-3,-3],[-4,-3],[-3,-2],[-77,-44],[-26,100],[-1,5],[-22,81],[-2,9],[-2,9],[-2,9],[-2,11],[-2,8],[-1,9],[-5,26],[-4,-2],[-39,-19],[-44,-12],[-5,-0],[-31,-5],[-10,-1],[-17,-2],[-35,-8],[6,43],[3,26],[2,10],[-1,-1],[-12,-5],[-13,-7],[-8,-4],[-31,-15],[-38,-19],[-16,-7],[-67,-11],[-33,-1],[-12,-6],[-33,-25],[-16,-6],[-28,-6],[-30,-3],[-10,3],[-11,7],[-18,16],[-8,5],[-11,9],[-29,13],[-24,14],[-14,8],[-2,4],[0,5],[49,60],[24,30],[-4,10],[-1,3],[-2,3],[-20,44],[-16,40],[-2,7],[-14,43],[-3,16],[-2,-5],[0,-1],[-1,-0],[0,-1],[-1,-0],[-1,-0],[0,1],[-48,67],[13,34],[-2,2],[-12,12],[-1,1],[-1,1],[-9,9],[-4,4],[-5,5],[-1,1],[-27,27],[-5,5],[3,43],[7,21],[9,26],[2,6],[12,34],[-15,9],[-33,22],[-30,19],[0,4],[3,32],[1,9],[2,19],[2,27],[1,12],[1,4],[-77,147],[-75,142],[0,-1],[-11,9],[-36,31],[-33,30],[-3,3],[-8,10],[6,27],[0,33],[-1,17],[62,185],[22,116],[20,108],[-6,9],[-8,12],[-12,19],[-76,-168],[-250,-437],[-51,-103],[-38,-86],[-18,-53],[-14,-58],[-41,-212],[-18,-72],[-27,-58],[-35,-41],[-38,-25],[-41,-5],[-40,18],[-35,36],[-132,161],[-26,28],[-29,20]],[[8580,-7934],[17,-15],[2,-2],[5,-5],[13,-14],[14,-14],[7,30],[7,43],[2,35],[2,46],[2,45],[0,12],[1,10],[0,5],[2,14],[1,10],[4,16],[3,12],[4,13],[4,10],[2,5],[3,7],[9,18],[8,18],[3,7],[5,12],[2,5],[5,17],[5,24],[2,8],[7,-3],[4,37],[2,38],[2,120],[2,47],[0,6],[0,6],[1,5],[0,5],[1,4],[1,3],[0,4],[4,15],[9,23],[1,3],[7,21],[4,12],[1,3],[4,16],[2,16],[2,17],[0,18],[0,17],[-2,17],[-3,17],[5,6],[1,1],[-3,13],[-5,17],[-6,17],[-3,15],[-1,5],[-2,9],[-2,15],[-1,15],[-5,96],[1,5],[5,1],[-9,80]],[[4634,-1600],[-29,47],[-9,14],[-21,21],[-7,17],[0,41],[1,16],[-7,16],[-14,27],[-2,4],[-26,48],[-19,25],[-14,21],[-9,15],[-16,-34],[-5,6],[-1,3],[-5,7],[-18,26],[-12,18],[-10,14],[-10,18],[-3,5],[-7,18],[-7,20],[-11,32],[-2,-7],[-5,-15],[-2,-9],[-1,-11],[0,-19],[-1,-23],[-1,-7],[-3,-10],[-2,-6],[-2,-8],[-4,-13],[-3,-10],[-4,-13],[-1,-3],[0,-16],[-1,-4],[-1,-3],[-6,-18],[-1,-3],[-5,-10],[-2,-3],[-2,-4],[-8,-18],[-6,-12],[-2,-4],[-2,-5],[-3,-8],[-2,-5],[-8,-21],[-34,-79],[15,-45],[3,-1],[20,-19],[-14,-65],[-1,-3],[2,-18],[1,-6],[10,-90],[0,-2],[2,-12],[1,-12],[8,-70],[-5,-11],[-12,6],[-13,1],[-11,-0],[-3,-1],[-8,-7],[-10,-9],[-3,-4],[-13,-3],[-22,-2],[-28,-5],[-6,-1],[-4,33],[-8,68],[-3,25],[-1,4],[-1,-0],[-27,4],[-13,2],[-24,3],[-33,3],[-27,10],[-27,10],[-1,-0],[1,-41],[0,-7],[0,-53],[0,-48],[0,-4],[0,-27],[-18,7],[-14,5],[-18,4],[-28,6],[-3,5],[0,7],[-3,-21],[-1,-3],[-3,1],[-31,13],[-39,20],[-49,22],[0,13],[-39,48],[-9,-22],[-17,-20],[-13,-13],[-36,-15],[-18,-13],[-25,68],[-6,17],[21,54],[26,68],[1,4],[4,49],[-9,17],[-12,20],[-45,66],[-37,43],[-2,2],[-27,19],[-27,20],[-19,7],[-28,8],[-10,-0],[-23,6],[-16,11],[-8,5],[-33,18],[-23,5],[-29,7],[-33,7],[-10,6],[-10,7],[3,50],[2,36],[1,75],[1,35],[-34,4],[-22,2],[-23,1],[-25,-2],[-18,-2],[-25,-2],[-7,1],[-16,5],[-15,5],[-35,12],[-23,12],[-26,12],[-25,5],[-24,3],[-4,-0],[-7,-2],[0,56],[0,41],[1,13],[-29,4],[-18,-1],[-20,-1],[-15,-1],[-6,-1],[-10,2],[-25,10],[-21,7],[-36,17],[-37,30],[-33,12],[-46,32],[-48,9],[-30,1],[-23,1],[-37,7],[-12,2],[-72,34],[-141,26],[-4,1],[-91,17],[28,685],[-202,30],[-202,30],[-188,28],[-26,-642],[-7,-23],[-3,-15],[-4,-15],[-8,-31],[-3,1],[-11,-18],[-12,-29],[-8,-18],[-26,-6],[-25,-36],[1,-18],[0,-6],[-5,-2],[-5,-2],[-5,-1],[-5,-2],[-5,-0],[-5,-1],[-5,-0],[-43,-1],[-2,-0],[-14,2],[-35,10],[-25,4],[-22,-2],[0,2],[-12,-7],[-3,-3],[-4,-2],[-3,-2],[-3,-2],[-4,-1],[-3,-2],[-4,-0],[-4,-1],[-3,1],[-4,-0],[-5,1],[-4,1],[-5,2],[-5,2],[-4,2],[-5,3],[-5,3],[-28,28],[-16,12],[-47,28],[-4,2],[-5,3],[-4,3],[-4,3],[-6,4],[-5,5],[-5,5],[-74,81],[-38,46],[-4,5],[-4,5],[-5,5],[-4,4],[-5,5],[-5,4],[-5,4],[-5,4],[-73,46],[-45,31],[-75,40],[-9,3],[-8,4],[-9,2],[-9,3],[-8,2],[-9,2],[-10,2],[-9,2],[-10,1],[-10,-0],[-10,1],[-40,-0],[-15,2],[-4,1],[-5,1],[-4,-0],[-5,-0],[-4,-1],[-5,-1],[-43,-10],[-32,-0],[-58,-6],[-33,-7],[-37,-17],[-79,-18],[-38,-12],[-79,-17],[-28,-2],[-10,3],[-22,-0],[-29,-5],[-68,1],[-20,2],[-8,-20],[-21,-67],[-4,-23],[0,-13],[7,-34],[21,-72],[3,-8],[6,-20],[17,-49],[18,-33],[21,-64],[9,-21],[13,-26],[14,-20],[2,-8],[6,-18],[8,-20],[29,-68],[6,-19],[17,-43],[10,-18],[14,-13],[6,-15],[12,-17],[23,-18],[9,-10],[18,-5],[7,-3],[23,-9],[7,-0],[22,-17],[2,-8],[5,-7],[-1,-2],[15,-2],[7,-10],[15,-35],[5,-15],[10,-33],[7,-30],[8,-20],[7,-8],[15,-14],[15,-21],[9,-10],[10,-23],[9,-26],[10,-14],[9,-11],[9,-2],[22,-12],[8,-5],[16,-21],[5,-14],[16,-2],[8,-18],[6,-27],[4,-14],[3,-20],[-7,-48],[-8,-52],[-9,-25],[-12,-38],[-11,-34],[-9,-27],[-2,-7],[20,-14],[17,-14],[-10,-62],[-2,-25],[-5,-22],[-2,-7],[-2,-15],[-5,-22],[-6,-13],[-5,-13],[-3,-26],[-3,-36],[-8,-16],[-21,-35],[-3,-20],[1,-57],[-7,-56],[9,-34],[6,-29],[3,-26],[1,-43],[-1,-14],[0,-16],[1,-38],[-3,-38],[-3,-29],[0,-17],[3,-12],[25,-58],[8,-11],[5,-5],[12,-17],[9,-9],[12,-10],[10,-6],[3,-4],[3,-12],[-2,-11],[-6,-11],[14,-28],[-4,-23],[0,-7],[-1,-16],[9,-6],[10,-4],[2,-0],[0,-14],[0,-34],[51,-54],[96,-104],[1,-0],[5,-2],[3,3],[23,1],[11,-3],[9,-7],[12,-3],[6,-4],[27,-9],[18,-2],[8,-3],[7,-3],[6,1],[1,-0],[14,-4],[12,-1],[5,-3],[23,-5],[1,2],[3,-2],[2,-6],[5,-9],[3,-2],[4,-8],[3,-7],[29,-43],[5,-9],[4,-4],[5,-5],[8,3],[1,-1],[4,-4],[7,4],[12,13],[6,3],[4,-2],[6,4],[13,11],[2,-3],[14,5],[7,-4],[10,4],[8,-1],[3,-4],[3,-1],[8,-6],[7,-4],[4,-6],[5,-3],[6,-2],[4,3],[5,-3],[3,-2],[6,3],[6,-10],[7,4],[7,-6],[11,-2],[3,-0],[3,5],[3,-7],[4,-3],[2,6],[3,1],[18,-19],[3,4],[8,-5],[3,-5],[10,-6],[25,-6],[7,-1],[10,-3],[6,-7],[19,-8],[14,-4],[6,-5],[2,-3],[13,-4],[3,1],[4,-5],[8,-1],[9,-11],[8,4],[13,-3],[6,3],[9,-1],[5,-3],[15,-0],[3,-2],[1,2],[14,-7],[5,-0],[18,-7],[8,-1],[6,-4],[3,-0],[2,-5],[-1,-13],[6,-5],[2,-11],[-1,-7],[4,-5],[2,-13],[6,-8],[5,-16],[6,-7],[10,-32],[0,-4],[3,-7],[10,-17],[15,-36],[6,-44],[-4,-27],[2,-10],[5,-9],[12,-12],[6,-14],[3,-10],[20,-35],[20,-35],[3,-9],[32,-41],[6,-4],[5,-3],[14,-4],[6,-2],[13,-3],[12,-2],[22,-2],[11,-6],[4,1],[12,-0],[12,-4],[22,-8],[11,17],[4,10],[1,2],[3,10],[2,12],[0,4],[0,1],[3,3],[19,14],[13,3],[8,-1],[5,2],[14,-2],[9,-0],[11,-2],[14,1],[-4,-15],[0,-9],[1,-0],[10,3],[10,1],[9,-5],[8,16],[4,-4],[5,-2],[9,6],[7,-0],[22,9],[7,4],[3,-0],[7,7],[6,4],[12,-0],[3,-3],[1,-1],[18,-3],[4,-2],[3,-2],[9,-3],[10,-15],[10,-7],[8,-8],[7,3],[15,-2],[2,-2],[10,-0],[2,-0],[4,1],[2,-0],[2,8],[5,8],[6,1],[7,10],[3,4],[8,-3],[13,4],[3,-3],[9,1],[4,3],[14,1],[3,2],[9,-2],[7,3],[8,-2],[11,-11],[5,-2],[4,-2],[17,-9],[10,7],[6,9],[8,7],[12,-1],[0,-10],[0,-29],[5,-117],[32,14],[2,-10],[1,-6],[1,-5],[49,-5],[6,-2],[25,-11],[-2,-21],[-12,-123],[-5,-56],[156,-89],[2,-1],[2,36],[1,25],[6,124],[22,-20],[4,-4],[3,12],[-1,9],[0,4],[1,8],[5,21],[2,16],[1,14],[5,5],[7,-4],[35,-20],[6,-2],[23,2],[15,-12],[8,-19],[16,-18],[12,-11],[12,-4],[17,-12],[15,-13],[18,-12],[-2,-7],[-24,-147],[-14,-80],[35,-18],[51,-21],[6,-5],[5,-1],[5,-34],[6,-38],[6,-40],[2,-13],[3,-24],[6,-42],[1,-5],[101,31],[21,8],[65,19],[19,8],[5,4],[14,10],[18,16],[11,10],[0,-33],[-1,-35],[0,-7],[32,-22],[19,-21],[31,-36],[27,-43],[25,-35],[1,-1],[17,-28],[25,-35],[21,-25],[32,-41],[30,-42],[6,-7],[20,-29],[31,-46],[24,-48],[17,-40],[10,-10],[18,-14],[13,-17],[4,-5],[14,-25],[26,-50],[31,-30],[15,-7],[24,-34],[27,-71],[17,-31],[2,-8],[5,-17],[-9,-13],[57,-188],[-14,-18],[-19,-23],[56,-141],[5,-11],[22,-56],[175,126],[173,-229],[105,-564],[4,-6],[125,-110],[76,-13]],[[4771,-5172],[1,8],[4,38]]],"transform":{"scale":[1.5327940836562959,0.7901219115706636],"translate":[2589007.980981961,1196443.1710116453]}} diff --git a/src/onegov/election_day/static/mapdata/2025/ag.json b/src/onegov/election_day/static/mapdata/2025/ag.json new file mode 100644 index 0000000000..c3371b54e0 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/ag.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":4001,"properties":{"id":4001,"name":"Aarau"},"arcs":[[-1,-2,-3,-4,-5,-6,-7,-8]]},{"type":"Polygon","id":4002,"properties":{"id":4002,"name":"Biberstein"},"arcs":[[-9,-10,-11,-12,6]]},{"type":"Polygon","id":4003,"properties":{"id":4003,"name":"Buchs (AG)"},"arcs":[[-13,-14,0]]},{"type":"Polygon","id":4004,"properties":{"id":4004,"name":"Densbüren"},"arcs":[[-15,-16,-17,-18,-19,-20]]},{"type":"Polygon","id":4005,"properties":{"id":4005,"name":"Erlinsbach (AG)"},"arcs":[[4,-21,-22,-23]]},{"type":"Polygon","id":4006,"properties":{"id":4006,"name":"Gränichen"},"arcs":[[-24,-25,-26,-27,-28,-29,-30,-31]]},{"type":"Polygon","id":4007,"properties":{"id":4007,"name":"Hirschthal"},"arcs":[[-32,-33,-34,-35]]},{"type":"Polygon","id":4008,"properties":{"id":4008,"name":"Küttigen"},"arcs":[[22,-36,15,-37,8,5]]},{"type":"Polygon","id":4009,"properties":{"id":4009,"name":"Muhen"},"arcs":[[-38,-39,28,-40,33,-41]]},{"type":"Polygon","id":4010,"properties":{"id":4010,"name":"Oberentfelden"},"arcs":[[-42,-43,-44,-45,29,38]]},{"type":"Polygon","id":4012,"properties":{"id":4012,"name":"Suhr"},"arcs":[[13,-46,-47,30,44,-48,1]]},{"type":"Polygon","id":4013,"properties":{"id":4013,"name":"Unterentfelden"},"arcs":[[47,43,-49,2]]},{"type":"MultiPolygon","id":4021,"properties":{"id":4021,"name":"Baden"},"arcs":[[[-50,-51,-52,-53,-54,-55,-56,-57]],[[-58,-59,-60]]]},{"type":"Polygon","id":4022,"properties":{"id":4022,"name":"Bellikon"},"arcs":[[-61,-62,-63,-64,-65,-66]]},{"type":"Polygon","id":4023,"properties":{"id":4023,"name":"Bergdietikon"},"arcs":[[-67,-68,60,-69,-70]]},{"type":"Polygon","id":4024,"properties":{"id":4024,"name":"Birmenstorf (AG)"},"arcs":[[59,-71,-72,-73,-74,-75,-76,51,-77]]},{"type":"Polygon","id":4026,"properties":{"id":4026,"name":"Ennetbaden"},"arcs":[[-78,-79,-80,-81,55]]},{"type":"Polygon","id":4027,"properties":{"id":4027,"name":"Fislisbach"},"arcs":[[76,50,-82,-83,-84,-85,57]]},{"type":"Polygon","id":4028,"properties":{"id":4028,"name":"Freienwil"},"arcs":[[-86,-87,78,-88]]},{"type":"Polygon","id":4029,"properties":{"id":4029,"name":"Gebenstorf"},"arcs":[[-89,52,75,-90,-91]]},{"type":"Polygon","id":4030,"properties":{"id":4030,"name":"Killwangen"},"arcs":[[-92,-93,-94,-95]]},{"type":"Polygon","id":4031,"properties":{"id":4031,"name":"Künten"},"arcs":[[-96,-97,63,-98,-99,-100]]},{"type":"Polygon","id":4032,"properties":{"id":4032,"name":"Mägenwil"},"arcs":[[-101,-102,-103,-104,-105]]},{"type":"Polygon","id":4033,"properties":{"id":4033,"name":"Mellingen"},"arcs":[[84,-106,-107,-108,-109,70,58]]},{"type":"Polygon","id":4034,"properties":{"id":4034,"name":"Neuenhof"},"arcs":[[-110,-111,92,-112,81,49]]},{"type":"Polygon","id":4035,"properties":{"id":4035,"name":"Niederrohrdorf"},"arcs":[[-113,-114,105,83,-115]]},{"type":"Polygon","id":4037,"properties":{"id":4037,"name":"Oberrohrdorf"},"arcs":[[-116,-117,114,82,111,91]]},{"type":"Polygon","id":4038,"properties":{"id":4038,"name":"Obersiggenthal"},"arcs":[[87,77,54,-118,-119,-120,-121]]},{"type":"Polygon","id":4039,"properties":{"id":4039,"name":"Remetschwil"},"arcs":[[116,-122,64,96,-123,112]]},{"type":"Polygon","id":4040,"properties":{"id":4040,"name":"Spreitenbach"},"arcs":[[65,121,115,94,-124,-125,68]]},{"type":"Polygon","id":4041,"properties":{"id":4041,"name":"Stetten (AG)"},"arcs":[[-126,-127,106,113,122,95]]},{"type":"Polygon","id":4044,"properties":{"id":4044,"name":"Untersiggenthal"},"arcs":[[-128,117,53,88,-129,-130]]},{"type":"Polygon","id":4045,"properties":{"id":4045,"name":"Wettingen"},"arcs":[[56,80,-131,-132,-133,109]]},{"type":"Polygon","id":4046,"properties":{"id":4046,"name":"Wohlenschwil"},"arcs":[[-134,71,108,-135,-136,100]]},{"type":"Polygon","id":4047,"properties":{"id":4047,"name":"Würenlingen"},"arcs":[[118,127,-137,-138,-139,-140,-141]]},{"type":"MultiPolygon","id":4048,"properties":{"id":4048,"name":"Würenlos"},"arcs":[[[123,93,110,132,-142]],[[-143]]]},{"type":"Polygon","id":4049,"properties":{"id":4049,"name":"Ehrendingen"},"arcs":[[-144,-145,-146,130,79,86]]},{"type":"Polygon","id":4061,"properties":{"id":4061,"name":"Arni (AG)"},"arcs":[[-147,-148,-149,-150,-151,-152,-153]]},{"type":"Polygon","id":4062,"properties":{"id":4062,"name":"Berikon"},"arcs":[[-154,-155,-156,-157,-158]]},{"type":"Polygon","id":4063,"properties":{"id":4063,"name":"Bremgarten (AG)"},"arcs":[[-159,-160,-161,-162,-163,-164,-165,-166,-167]]},{"type":"Polygon","id":4064,"properties":{"id":4064,"name":"Büttikon"},"arcs":[[-168,-169,-170,-171,-172]]},{"type":"Polygon","id":4065,"properties":{"id":4065,"name":"Dottikon"},"arcs":[[-173,-174,-175,-176,-177]]},{"type":"Polygon","id":4066,"properties":{"id":4066,"name":"Eggenwil"},"arcs":[[-178,163,-179,97,62,-180]]},{"type":"Polygon","id":4067,"properties":{"id":4067,"name":"Fischbach-Göslikon"},"arcs":[[-181,98,178,162,-182]]},{"type":"Polygon","id":4068,"properties":{"id":4068,"name":"Hägglingen"},"arcs":[[101,135,-183,-184,-185,174,-186]]},{"type":"Polygon","id":4071,"properties":{"id":4071,"name":"Jonen"},"arcs":[[-187,-188,-189,148,-190]]},{"type":"Polygon","id":4072,"properties":{"id":4072,"name":"Niederwil (AG)"},"arcs":[[-191,183,-192,125,99,180]]},{"type":"Polygon","id":4073,"properties":{"id":4073,"name":"Oberlunkhofen"},"arcs":[[-193,149,188,-194]]},{"type":"Polygon","id":4074,"properties":{"id":4074,"name":"Oberwil-Lieli"},"arcs":[[157,-195,151,-196,-197]]},{"type":"Polygon","id":4075,"properties":{"id":4075,"name":"Rudolfstetten-Friedlisberg"},"arcs":[[-198,66,-199,155]]},{"type":"Polygon","id":4076,"properties":{"id":4076,"name":"Sarmenstorf"},"arcs":[[-200,-201,-202,168,-203,-204,-205,-206]]},{"type":"Polygon","id":4077,"properties":{"id":4077,"name":"Tägerig"},"arcs":[[107,126,191,182,134]]},{"type":"Polygon","id":4078,"properties":{"id":4078,"name":"Uezwil"},"arcs":[[-207,-208,202,167]]},{"type":"Polygon","id":4079,"properties":{"id":4079,"name":"Unterlunkhofen"},"arcs":[[150,192,-209,165,-210,195]]},{"type":"Polygon","id":4080,"properties":{"id":4080,"name":"Villmergen"},"arcs":[[176,-211,169,201,-212,-213,-214]]},{"type":"Polygon","id":4081,"properties":{"id":4081,"name":"Widen"},"arcs":[[179,61,67,197,154,-215]]},{"type":"Polygon","id":4082,"properties":{"id":4082,"name":"Wohlen (AG)"},"arcs":[[181,161,-216,170,210,175,184,190]]},{"type":"Polygon","id":4083,"properties":{"id":4083,"name":"Zufikon"},"arcs":[[214,153,196,209,164,177]]},{"type":"Polygon","id":4084,"properties":{"id":4084,"name":"Islisberg"},"arcs":[[146,-217]]},{"type":"Polygon","id":4091,"properties":{"id":4091,"name":"Auenstein"},"arcs":[[-218,-219,-220,-221,10,-222]]},{"type":"Polygon","id":4092,"properties":{"id":4092,"name":"Birr"},"arcs":[[-223,-224,-225,-226]]},{"type":"Polygon","id":4093,"properties":{"id":4093,"name":"Birrhard"},"arcs":[[222,-227,-228,72,133,104,-229]]},{"type":"Polygon","id":4095,"properties":{"id":4095,"name":"Brugg"},"arcs":[[-230,-231,-232,128,90,-233,-234,-235,-236,-237,-238,-239,-240]]},{"type":"Polygon","id":4099,"properties":{"id":4099,"name":"Habsburg"},"arcs":[[-241,234,-242]]},{"type":"Polygon","id":4100,"properties":{"id":4100,"name":"Hausen (AG)"},"arcs":[[241,233,-243,-244,-245]]},{"type":"Polygon","id":4104,"properties":{"id":4104,"name":"Lupfig"},"arcs":[[-246,235,240,244,-247,226,225,-248]]},{"type":"Polygon","id":4105,"properties":{"id":4105,"name":"Mandach"},"arcs":[[-249,-250,-251,-252]]},{"type":"Polygon","id":4106,"properties":{"id":4106,"name":"Mönthal"},"arcs":[[-253,-254,-255,-256,-257]]},{"type":"Polygon","id":4107,"properties":{"id":4107,"name":"Mülligen"},"arcs":[[-258,73,227,246,243]]},{"type":"Polygon","id":4110,"properties":{"id":4110,"name":"Remigen"},"arcs":[[252,-259,-260,-261,-262,-263,-264]]},{"type":"Polygon","id":4111,"properties":{"id":4111,"name":"Riniken"},"arcs":[[-265,229,-266,262]]},{"type":"Polygon","id":4112,"properties":{"id":4112,"name":"Rüfenach"},"arcs":[[261,-267,230,264]]},{"type":"Polygon","id":4117,"properties":{"id":4117,"name":"Thalheim (AG)"},"arcs":[[-268,-269,221,9,36,14]]},{"type":"Polygon","id":4120,"properties":{"id":4120,"name":"Veltheim (AG)"},"arcs":[[-270,218,-271,-272]]},{"type":"Polygon","id":4121,"properties":{"id":4121,"name":"Villigen"},"arcs":[[-273,249,-274,136,129,231,266,260]]},{"type":"Polygon","id":4122,"properties":{"id":4122,"name":"Villnachern"},"arcs":[[238,-275,-276]]},{"type":"Polygon","id":4123,"properties":{"id":4123,"name":"Windisch"},"arcs":[[242,232,89,74,257]]},{"type":"Polygon","id":4124,"properties":{"id":4124,"name":"Bözberg"},"arcs":[[263,265,239,275,-277,-278,-279,253]]},{"type":"Polygon","id":4125,"properties":{"id":4125,"name":"Schinznach"},"arcs":[[274,237,270,217,268,-280,276]]},{"type":"Polygon","id":4131,"properties":{"id":4131,"name":"Beinwil am See"},"arcs":[[-281,-282,-283,-284,-285]]},{"type":"Polygon","id":4132,"properties":{"id":4132,"name":"Birrwil"},"arcs":[[-286,-287,282,-288,-289,-290]]},{"type":"Polygon","id":4134,"properties":{"id":4134,"name":"Dürrenäsch"},"arcs":[[-291,-292,-293,-294,-295,-296,-297,-298]]},{"type":"Polygon","id":4135,"properties":{"id":4135,"name":"Gontenschwil"},"arcs":[[-299,-300,-301,-302,-303,-304]]},{"type":"Polygon","id":4136,"properties":{"id":4136,"name":"Holziken"},"arcs":[[40,32,-305,-306,-307]]},{"type":"Polygon","id":4137,"properties":{"id":4137,"name":"Leimbach (AG)"},"arcs":[[303,-308,-309]]},{"type":"Polygon","id":4138,"properties":{"id":4138,"name":"Leutwil"},"arcs":[[289,-310,294,-311]]},{"type":"Polygon","id":4139,"properties":{"id":4139,"name":"Menziken"},"arcs":[[-312,280,-313]]},{"type":"Polygon","id":4140,"properties":{"id":4140,"name":"Oberkulm"},"arcs":[[-314,-315,-316,296,-317,301]]},{"type":"Polygon","id":4141,"properties":{"id":4141,"name":"Reinach (AG)"},"arcs":[[308,-318,287,281,311,-319,298]]},{"type":"Polygon","id":4142,"properties":{"id":4142,"name":"Schlossrued"},"arcs":[[-320,-321,-322,314,-323,-324]]},{"type":"Polygon","id":4143,"properties":{"id":4143,"name":"Schmiedrued"},"arcs":[[300,-325,-326,-327,322,313]]},{"type":"Polygon","id":4144,"properties":{"id":4144,"name":"Schöftland"},"arcs":[[-328,320,-329,-330,304,31]]},{"type":"Polygon","id":4145,"properties":{"id":4145,"name":"Teufenthal (AG)"},"arcs":[[-331,26,-332,290]]},{"type":"Polygon","id":4146,"properties":{"id":4146,"name":"Unterkulm"},"arcs":[[34,39,27,330,297,315,321,327]]},{"type":"Polygon","id":4147,"properties":{"id":4147,"name":"Zetzwil"},"arcs":[[295,309,288,317,307,302,316]]},{"type":"Polygon","id":4161,"properties":{"id":4161,"name":"Eiken"},"arcs":[[-333,-334,-335,-336,-337,-338,-339]]},{"type":"Polygon","id":4163,"properties":{"id":4163,"name":"Frick"},"arcs":[[-340,335,-341,-342,-343,-344,-345]]},{"type":"Polygon","id":4164,"properties":{"id":4164,"name":"Gansingen"},"arcs":[[256,-346,-347,258]]},{"type":"Polygon","id":4165,"properties":{"id":4165,"name":"Gipf-Oberfrick"},"arcs":[[344,-348,-349,-350,-351]]},{"type":"Polygon","id":4169,"properties":{"id":4169,"name":"Kaisten"},"arcs":[[-352,-353,341,-354,333,-355]]},{"type":"Polygon","id":4170,"properties":{"id":4170,"name":"Laufenburg"},"arcs":[[-356,-357,345,255,-358,351]]},{"type":"Polygon","id":4172,"properties":{"id":4172,"name":"Münchwilen (AG)"},"arcs":[[-359,-360,-361,337,-362]]},{"type":"Polygon","id":4173,"properties":{"id":4173,"name":"Oberhof"},"arcs":[[-363,16,35,21,-364]]},{"type":"Polygon","id":4175,"properties":{"id":4175,"name":"Oeschgen"},"arcs":[[340,334,353]]},{"type":"Polygon","id":4176,"properties":{"id":4176,"name":"Schwaderloch"},"arcs":[[-365,-366,-367]]},{"type":"Polygon","id":4177,"properties":{"id":4177,"name":"Sisseln"},"arcs":[[338,360,-368,-369]]},{"type":"Polygon","id":4181,"properties":{"id":4181,"name":"Wittnau"},"arcs":[[-370,-371,-372,349]]},{"type":"Polygon","id":4182,"properties":{"id":4182,"name":"Wölflinswil"},"arcs":[[-373,369,348,-374,17,362]]},{"type":"Polygon","id":4183,"properties":{"id":4183,"name":"Zeihen"},"arcs":[[-375,277,279,267,19,-376]]},{"type":"Polygon","id":4184,"properties":{"id":4184,"name":"Mettauertal"},"arcs":[[259,346,356,-377,365,-378,-379,250,272]]},{"type":"Polygon","id":4185,"properties":{"id":4185,"name":"Böztal"},"arcs":[[-380,342,352,357,254,278,374]]},{"type":"Polygon","id":4186,"properties":{"id":4186,"name":"Herznach-Ueken"},"arcs":[[375,18,373,347,343,379]]},{"type":"Polygon","id":4191,"properties":{"id":4191,"name":"Ammerswil"},"arcs":[[-381,-382,-383,-384]]},{"type":"Polygon","id":4192,"properties":{"id":4192,"name":"Boniswil"},"arcs":[[310,293,-385,-386,285]]},{"type":"Polygon","id":4193,"properties":{"id":4193,"name":"Brunegg"},"arcs":[[228,103,-387,-388,223]]},{"type":"Polygon","id":4194,"properties":{"id":4194,"name":"Dintikon"},"arcs":[[212,-389,382,-390]]},{"type":"Polygon","id":4195,"properties":{"id":4195,"name":"Egliswil"},"arcs":[[383,388,-391,-392,-393]]},{"type":"Polygon","id":4196,"properties":{"id":4196,"name":"Fahrwangen"},"arcs":[[205,-394,-395,283,-396]]},{"type":"Polygon","id":4197,"properties":{"id":4197,"name":"Hallwil"},"arcs":[[-397,-398,384,292]]},{"type":"Polygon","id":4198,"properties":{"id":4198,"name":"Hendschiken"},"arcs":[[213,389,381,-399,-400,172]]},{"type":"Polygon","id":4199,"properties":{"id":4199,"name":"Holderbank (AG)"},"arcs":[[-401,271,236,245]]},{"type":"Polygon","id":4200,"properties":{"id":4200,"name":"Hunzenschwil"},"arcs":[[46,-402,-403,23]]},{"type":"Polygon","id":4201,"properties":{"id":4201,"name":"Lenzburg"},"arcs":[[-404,-405,-406,-407,398,380,392,-408,-409]]},{"type":"Polygon","id":4202,"properties":{"id":4202,"name":"Meisterschwanden"},"arcs":[[199,395,286,-410]]},{"type":"Polygon","id":4203,"properties":{"id":4203,"name":"Möriken-Wildegg"},"arcs":[[247,224,387,-411,405,-412,-413,219,269,400]]},{"type":"Polygon","id":4204,"properties":{"id":4204,"name":"Niederlenz"},"arcs":[[404,-414,411]]},{"type":"Polygon","id":4205,"properties":{"id":4205,"name":"Othmarsingen"},"arcs":[[399,406,410,386,102,185,173]]},{"type":"Polygon","id":4206,"properties":{"id":4206,"name":"Rupperswil"},"arcs":[[-415,-416,401,45,12,7,11,220,412,413,403]]},{"type":"Polygon","id":4207,"properties":{"id":4207,"name":"Schafisheim"},"arcs":[[402,415,-417,-418,24]]},{"type":"Polygon","id":4208,"properties":{"id":4208,"name":"Seengen"},"arcs":[[409,385,397,-419,390,211,200]]},{"type":"Polygon","id":4209,"properties":{"id":4209,"name":"Seon"},"arcs":[[331,25,417,-420,407,391,418,396,291]]},{"type":"Polygon","id":4210,"properties":{"id":4210,"name":"Staufen"},"arcs":[[408,419,416,414]]},{"type":"Polygon","id":4221,"properties":{"id":4221,"name":"Abtwil"},"arcs":[[-421,-422]]},{"type":"Polygon","id":4222,"properties":{"id":4222,"name":"Aristau"},"arcs":[[-423,-424,-425,-426,186,-427,-428]]},{"type":"Polygon","id":4223,"properties":{"id":4223,"name":"Auw"},"arcs":[[-429,-430,-431,-432]]},{"type":"Polygon","id":4224,"properties":{"id":4224,"name":"Beinwil (Freiamt)"},"arcs":[[-433,-434,-435,428,-436]]},{"type":"Polygon","id":4226,"properties":{"id":4226,"name":"Besenbüren"},"arcs":[[-437,424,-438,-439,158]]},{"type":"Polygon","id":4227,"properties":{"id":4227,"name":"Bettwil"},"arcs":[[204,-440,-441,-442,-443,393]]},{"type":"Polygon","id":4228,"properties":{"id":4228,"name":"Boswil"},"arcs":[[-444,440,-445,-446,-447,437,423,-448]]},{"type":"Polygon","id":4229,"properties":{"id":4229,"name":"Bünzen"},"arcs":[[-449,159,438,446]]},{"type":"Polygon","id":4230,"properties":{"id":4230,"name":"Buttwil"},"arcs":[[-450,-451,-452,441,443]]},{"type":"Polygon","id":4231,"properties":{"id":4231,"name":"Dietwil"},"arcs":[[-453,-454,-455]]},{"type":"Polygon","id":4232,"properties":{"id":4232,"name":"Geltwil"},"arcs":[[-456,450,-457,-458,432]]},{"type":"Polygon","id":4233,"properties":{"id":4233,"name":"Kallern"},"arcs":[[207,-459,444,439,203]]},{"type":"Polygon","id":4234,"properties":{"id":4234,"name":"Merenschwand"},"arcs":[[-460,433,457,-461,427,-462]]},{"type":"Polygon","id":4235,"properties":{"id":4235,"name":"Mühlau"},"arcs":[[-463,429,434,459,-464]]},{"type":"Polygon","id":4236,"properties":{"id":4236,"name":"Muri (AG)"},"arcs":[[460,456,449,447,422]]},{"type":"Polygon","id":4237,"properties":{"id":4237,"name":"Oberrüti"},"arcs":[[-465,-466,453]]},{"type":"Polygon","id":4238,"properties":{"id":4238,"name":"Rottenschwil"},"arcs":[[166,208,193,187,425,436]]},{"type":"Polygon","id":4239,"properties":{"id":4239,"name":"Sins"},"arcs":[[-467,420,-468,430,462,-469,464,452]]},{"type":"Polygon","id":4240,"properties":{"id":4240,"name":"Waltenschwil"},"arcs":[[171,215,160,448,445,458,206]]},{"type":"Polygon","id":4251,"properties":{"id":4251,"name":"Hellikon"},"arcs":[[-470,-471,-472,-473,-474]]},{"type":"Polygon","id":4252,"properties":{"id":4252,"name":"Kaiseraugst"},"arcs":[[-475,-476,-477]]},{"type":"Polygon","id":4253,"properties":{"id":4253,"name":"Magden"},"arcs":[[-478,-479,-480,-481,-482,-483,-484,-485]]},{"type":"Polygon","id":4254,"properties":{"id":4254,"name":"Möhlin"},"arcs":[[483,-486,-487,-488,-489,-490]]},{"type":"Polygon","id":4255,"properties":{"id":4255,"name":"Mumpf"},"arcs":[[-491,-492,-493,-494,-495,-496]]},{"type":"Polygon","id":4256,"properties":{"id":4256,"name":"Obermumpf"},"arcs":[[495,-497,358,-498,470,-499]]},{"type":"MultiPolygon","id":4257,"properties":{"id":4257,"name":"Olsberg"},"arcs":[[[-500,481,-501,476]],[[479,-502]],[[-503,477]]]},{"type":"Polygon","id":4258,"properties":{"id":4258,"name":"Rheinfelden"},"arcs":[[-504,485,482,499,475]]},{"type":"Polygon","id":4259,"properties":{"id":4259,"name":"Schupfart"},"arcs":[[497,361,336,339,350,-505,471]]},{"type":"Polygon","id":4260,"properties":{"id":4260,"name":"Stein (AG)"},"arcs":[[496,494,-506,367,359]]},{"type":"Polygon","id":4261,"properties":{"id":4261,"name":"Wallbach"},"arcs":[[-507,492,-508,487]]},{"type":"Polygon","id":4262,"properties":{"id":4262,"name":"Wegenstetten"},"arcs":[[472,504,371,-509]]},{"type":"Polygon","id":4263,"properties":{"id":4263,"name":"Zeiningen"},"arcs":[[-510,488,507,491,-511]]},{"type":"Polygon","id":4264,"properties":{"id":4264,"name":"Zuzgen"},"arcs":[[-512,510,490,498,469]]},{"type":"Polygon","id":4271,"properties":{"id":4271,"name":"Aarburg"},"arcs":[[-513,-514,-515]]},{"type":"Polygon","id":4273,"properties":{"id":4273,"name":"Bottenwil"},"arcs":[[-516,-517,-518,-519,-520]]},{"type":"Polygon","id":4274,"properties":{"id":4274,"name":"Brittnau"},"arcs":[[-521,-522,-523,-524,-525]]},{"type":"Polygon","id":4275,"properties":{"id":4275,"name":"Kirchleerau"},"arcs":[[326,-526,-527,323]]},{"type":"Polygon","id":4276,"properties":{"id":4276,"name":"Kölliken"},"arcs":[[-528,41,37,306,-529,-530]]},{"type":"Polygon","id":4277,"properties":{"id":4277,"name":"Moosleerau"},"arcs":[[325,-531,-532,-533,525]]},{"type":"Polygon","id":4279,"properties":{"id":4279,"name":"Murgenthal"},"arcs":[[-534,-535,520,-536]]},{"type":"Polygon","id":4280,"properties":{"id":4280,"name":"Oftringen"},"arcs":[[-537,-538,514,-539,-540,-541]]},{"type":"Polygon","id":4281,"properties":{"id":4281,"name":"Reitnau"},"arcs":[[-542,-543,531,-544]]},{"type":"Polygon","id":4282,"properties":{"id":4282,"name":"Rothrist"},"arcs":[[533,-545,512,537,-546,-547]]},{"type":"Polygon","id":4283,"properties":{"id":4283,"name":"Safenwil"},"arcs":[[529,-548,-549,539,-550]]},{"type":"Polygon","id":4284,"properties":{"id":4284,"name":"Staffelbach"},"arcs":[[319,526,532,542,-551,518,-552,328]]},{"type":"Polygon","id":4285,"properties":{"id":4285,"name":"Strengelbach"},"arcs":[[-553,522,-554,545,536]]},{"type":"Polygon","id":4286,"properties":{"id":4286,"name":"Uerkheim"},"arcs":[[547,528,305,329,551,517,-555]]},{"type":"Polygon","id":4287,"properties":{"id":4287,"name":"Vordemwald"},"arcs":[[546,553,521,534]]},{"type":"Polygon","id":4288,"properties":{"id":4288,"name":"Wiliberg"},"arcs":[[519,550,541,-556]]},{"type":"Polygon","id":4289,"properties":{"id":4289,"name":"Zofingen"},"arcs":[[540,548,554,516,-557,523,552]]},{"type":"Polygon","id":4303,"properties":{"id":4303,"name":"Böttstein"},"arcs":[[-558,-559,-560,137,273,248]]},{"type":"Polygon","id":4304,"properties":{"id":4304,"name":"Döttingen"},"arcs":[[-561,138,559,-562,-563]]},{"type":"Polygon","id":4305,"properties":{"id":4305,"name":"Endingen"},"arcs":[[140,-564,-565,-566,119]]},{"type":"Polygon","id":4306,"properties":{"id":4306,"name":"Fisibach"},"arcs":[[-567,-568,-569,-570,-571]]},{"type":"Polygon","id":4307,"properties":{"id":4307,"name":"Full-Reuenthal"},"arcs":[[-572,-573,-574]]},{"type":"Polygon","id":4309,"properties":{"id":4309,"name":"Klingnau"},"arcs":[[-575,-576,561,558,-577]]},{"type":"Polygon","id":4310,"properties":{"id":4310,"name":"Koblenz"},"arcs":[[-578,574,-579,-580]]},{"type":"Polygon","id":4311,"properties":{"id":4311,"name":"Leibstadt"},"arcs":[[-581,377,364,-582,571]]},{"type":"Polygon","id":4312,"properties":{"id":4312,"name":"Lengnau (AG)"},"arcs":[[120,565,-583,-584,143,85]]},{"type":"Polygon","id":4313,"properties":{"id":4313,"name":"Leuggern"},"arcs":[[251,378,580,573,-585,578,576,557]]},{"type":"Polygon","id":4314,"properties":{"id":4314,"name":"Mellikon"},"arcs":[[-586,-587]]},{"type":"Polygon","id":4318,"properties":{"id":4318,"name":"Schneisingen"},"arcs":[[144,583,-588,-589,-590]]},{"type":"Polygon","id":4319,"properties":{"id":4319,"name":"Siglistorf"},"arcs":[[588,-591,566,-592]]},{"type":"Polygon","id":4320,"properties":{"id":4320,"name":"Tegerfelden"},"arcs":[[-593,563,139,560]]},{"type":"MultiPolygon","id":4324,"properties":{"id":4324,"name":"Zurzach"},"arcs":[[[582,564,592,562,575,577,-594,585,-595,567,590,587]],[[569,-596]]]}]}},"arcs":[[[47370,51654],[-154,212],[85,108],[-106,218],[187,89],[-101,237],[85,135],[-43,202],[425,147],[-81,204],[241,276],[373,96],[1020,-160],[305,-145],[149,156],[661,169],[380,1081],[99,182],[602,49],[538,153],[750,97],[641,-36],[451,-121]],[[46054,47656],[225,115],[262,33],[427,160],[533,275],[237,50],[-33,266],[-467,1218],[-297,93],[-437,229],[75,443],[126,152],[-123,171],[447,518],[341,275]],[[42351,47932],[285,-77],[280,318],[616,624],[-175,240],[289,160],[265,53],[928,-372],[311,-53],[148,-134],[70,-651],[85,-106],[428,107],[402,210],[-229,-595]],[[42204,53013],[451,-1900],[213,-571],[-65,-485],[-174,-422],[42,-331],[-92,-441],[-185,-283],[80,-218],[-87,-123],[-36,-307]],[[43452,54300],[-350,-109],[-288,-151],[-449,-383],[-12,-173],[-139,-275],[-10,-196]],[[48087,56089],[-439,-293],[-47,49],[-452,-271],[-296,-266],[-378,-209],[-428,-84],[-636,-462],[-279,-113],[-136,-162],[-272,-152],[-173,-183],[-207,178],[-412,171],[-480,8]],[[52591,56553],[-2429,-91],[-217,-47],[-287,-242],[-296,-119],[-293,-14],[-551,143],[-431,-94]],[[53877,55003],[-384,211],[-562,378],[-348,138],[8,823]],[[47659,60021],[120,-286],[66,-607],[-174,-344],[106,-146],[-35,-463],[-76,-280],[233,-317],[-190,-309],[18,-323],[233,-348],[-71,-227],[198,-282]],[[51825,58845],[-377,134],[-415,86],[-552,286],[-97,124],[-556,153],[-635,111],[-541,25],[-377,134],[-616,123]],[[52592,56571],[-146,716],[-271,511],[-356,132],[-128,211],[134,704]],[[52591,56553],[1,18]],[[54268,54032],[39,49],[-145,808],[-285,114]],[[47370,51654],[1267,-1731],[299,178],[68,-117],[292,143],[283,233],[20,122],[219,56],[48,-207],[323,-30],[59,154],[170,17],[409,278],[50,339],[347,33],[251,89],[19,155],[412,-28],[180,163],[677,104],[-357,560],[-433,-86],[-979,-255],[-266,141],[-248,248],[-149,337],[2873,729],[-61,123],[1134,676],[-9,-46]],[[47598,60548],[-20,169],[141,237],[-270,302],[75,421],[-181,47],[37,148],[-115,102],[-41,299],[244,175],[1148,117],[340,160],[-89,723],[-38,554],[444,-139],[433,15],[258,136],[37,471],[60,30],[-156,322],[110,52],[-66,374],[125,243],[343,52],[543,225]],[[42627,61371],[243,17],[99,256],[339,120],[693,-71],[336,-72],[25,-446],[146,22],[-6,-173],[285,168],[252,-81],[30,211],[758,100],[164,-281],[120,-64],[-19,-167],[361,-8],[206,-268],[254,40],[551,-70],[134,-56]],[[42560,64677],[44,-171],[223,-67],[-228,-645],[325,-140],[-215,-82],[190,-239],[-331,-526],[151,115],[396,-136],[-147,-115],[-257,-541],[27,-416],[-156,-144],[45,-199]],[[42424,66777],[-67,-33],[74,-490],[-30,-154],[68,-351],[-84,-309],[150,-56],[61,-471],[-36,-236]],[[48500,67621],[-784,-21],[-398,76],[-33,-181],[-259,115],[-123,158],[-500,32],[-140,-125],[-69,-243],[-382,-75],[-188,-120],[-236,35],[138,309],[-205,39],[-621,-249],[-247,99],[-140,157],[-358,-120],[-272,-374],[-196,-42],[-342,57],[-79,-277],[-319,-5],[-323,-89]],[[50960,65783],[-590,743],[-28,335],[-247,-34],[-116,165],[68,229],[-151,7],[-31,-168],[-234,133],[41,89],[-184,134],[-169,-7],[34,204],[-260,83],[-390,-101],[-203,26]],[[36874,59844],[-235,-1243],[-165,26],[-60,1123],[-154,4],[-343,-164],[-374,-255],[-440,-142],[-878,-458],[-578,-240],[828,-439],[396,-259],[261,109],[414,-702],[282,-166],[80,-141],[282,-206],[299,114],[466,-155],[235,168],[120,-432],[152,-178],[289,-19],[548,-226],[579,-119],[232,-165],[224,-297],[259,-115],[257,-1001],[126,-118],[1,-1194],[482,-210],[346,131],[515,-207],[46,377],[838,-32]],[[40642,60343],[-161,9],[-370,-128],[-1335,-122],[-734,-230],[-389,17],[-489,-102],[-290,57]],[[43452,54300],[-125,165],[-163,-187],[-315,93],[-48,230],[-555,2192],[-77,114],[-63,655],[-404,1015],[-517,-181],[-48,235],[-445,75],[-183,396],[77,501],[56,740]],[[55281,48293],[-106,157],[-365,173],[-173,159],[-104,218],[-314,384],[-190,130]],[[57087,45061],[-115,134],[-543,253],[-53,166],[-500,53],[-625,-70],[-284,291],[-47,293],[218,515],[154,181],[254,651],[-92,508],[-173,257]],[[57967,40511],[-192,480],[-315,408],[-95,222],[89,442],[-73,481],[-368,550],[-114,613],[6,316],[107,271],[75,767]],[[53737,40296],[227,-74],[170,386],[187,-76],[-101,-183],[296,80],[918,-350],[601,-37],[261,75],[289,206],[469,11],[336,102],[577,75]],[[50307,39615],[366,164],[-65,297],[416,336],[292,118],[506,127],[68,-65],[469,187],[106,-56],[119,305],[447,217],[461,15],[39,-423],[-55,-198],[105,-245],[156,-98]],[[48263,42219],[256,-279],[235,-25],[87,-254],[-94,-173],[294,-297],[270,-121],[131,-170],[283,-111],[105,-254],[108,-3],[203,-311],[13,-218],[153,-388]],[[48278,43384],[-74,-223],[18,-231],[132,-364],[-91,-347]],[[54029,49514],[-1597,-999],[-848,-730],[-445,-311],[-776,-445],[92,-73],[-275,-132],[95,-195],[-182,-592],[269,-195],[-499,-230],[-157,-241],[58,-208],[-126,-219],[-322,-111],[-115,78],[-220,-132],[-180,-210],[4,-400],[-355,-579],[-172,-206]],[[44575,37044],[105,-214],[114,181],[274,-57],[350,-293],[326,-97],[-31,-121],[557,-141],[483,-223],[376,-255],[495,-178],[139,18],[385,-172],[512,-61],[464,-199],[341,91],[352,-84]],[[44684,38284],[55,-491],[-165,-551],[1,-198]],[[50247,37822],[-376,107],[-463,-131],[-252,166],[-348,-81],[-344,-154],[-953,-177],[-559,129],[-426,311],[-569,244],[-8,192],[-1001,65],[44,-183],[-308,-26]],[[49817,35239],[392,362],[187,465],[-26,329],[52,321],[118,176],[-28,255],[-247,377],[-18,298]],[[42627,61371],[-827,10],[-390,-485],[-191,-512],[-577,-41]],[[47659,60021],[-166,33],[93,188],[12,306]],[[44864,42485],[51,-207],[-90,-143],[-403,-334],[-109,-158],[-62,-409],[119,-773],[260,-991],[-219,-16]],[[48263,42219],[-365,-163],[-410,-25],[-610,269],[-321,356],[-1004,276],[-62,97],[-368,-529],[-124,227],[-163,-47],[28,-195]],[[50247,37822],[81,327],[-105,339],[95,483],[-231,365],[220,279]],[[44411,39454],[224,-877],[49,-293]],[[40287,43496],[598,6],[365,-53],[451,6],[567,-44],[41,152],[284,-59],[442,-395],[104,113],[300,-266],[215,140],[-112,-351],[412,-94],[61,128],[363,-121],[115,-111],[371,-62]],[[41763,46634],[-471,-228],[-272,-275],[-114,-270],[27,-121],[-338,-234],[-176,-281],[-323,-250],[320,-541],[-26,-493],[-103,-445]],[[46581,45836],[-400,-232],[-287,279],[-158,-271],[-630,356],[-170,-229],[-595,560],[-114,171],[-527,90],[-349,250],[-376,-190],[-432,21],[-277,-191],[-503,184]],[[48278,43384],[11,136],[-140,244],[-411,335],[-238,738],[-258,269],[-167,-198],[-78,57],[193,385],[-205,228],[-74,-192],[-200,184],[-130,266]],[[54226,52317],[-13,1045],[-49,311],[104,359]],[[54029,49514],[-548,650],[111,211],[-200,183],[-140,391],[150,77],[-167,409],[-178,-8],[-140,178],[262,120],[567,347],[-28,54],[508,191]],[[46054,47656],[262,-593],[141,26],[110,-298],[-512,-273],[198,-348],[196,103],[208,-362],[-76,-75]],[[42351,47932],[-87,-507],[-207,-200],[-110,-453],[-184,-138]],[[79930,63671],[325,216],[154,244],[69,439],[-530,235],[-142,442],[-301,144],[-58,147],[432,295],[-147,310],[180,207],[295,-138],[-89,297],[176,237]],[[76272,64074],[652,-161],[429,-51],[408,-314],[56,-233],[319,74],[-128,324],[687,482],[237,-111],[881,-98],[117,-315]],[[74795,68347],[33,-492],[-26,-759],[197,-457],[-17,-258],[335,-211],[114,16],[76,-237],[-195,-102],[406,-496],[297,-597],[257,-680]],[[71671,73692],[2,-186],[128,-54],[13,-604],[312,-18],[-36,-134],[431,-260],[-146,-494],[293,-308],[123,-247],[341,113],[102,-170],[161,11],[130,-122],[219,36],[29,-353],[263,-242],[355,132],[12,-301],[-211,-400],[50,-352],[154,-564],[399,-828]],[[74118,72546],[-228,70],[-441,254],[-399,414],[-71,334],[31,501],[-130,197],[-263,-9],[-524,-437],[-422,-178]],[[80232,71281],[-456,75],[-737,-23],[-91,26],[-353,414],[-501,133],[-575,-136],[-222,-9],[-554,211],[-449,-20],[-479,-429],[-267,-68],[-485,75],[-137,68],[-97,218],[-16,388],[-105,274],[-112,72],[-478,-4]],[[80700,69649],[-478,-197],[-99,456],[90,283],[300,379],[261,450],[-118,242],[-424,19]],[[80294,66746],[-149,82],[-137,397],[25,360],[-59,313],[360,-135],[120,275],[17,449],[203,232],[146,-116],[135,233],[139,23],[318,626],[-269,109],[-443,55]],[[74711,61197],[-20,224],[450,39],[-22,253],[440,267],[104,660],[-433,375],[63,61]],[[74158,61327],[246,-212],[279,-59],[28,141]],[[75293,63076],[-207,284],[-368,-285],[-205,-76],[-367,-266],[148,-3],[-85,-314],[-188,-419],[-340,-222],[477,-448]],[[87670,50811],[-132,227],[-79,819],[-143,315],[-87,492],[-195,433],[-238,777],[-66,509],[46,806]],[[86013,49205],[504,339],[266,381],[475,293],[297,309],[115,284]],[[85327,49904],[77,-112],[196,163],[413,-750]],[[83381,54089],[-68,-49],[151,-375],[-150,-31],[256,-356],[395,-803],[145,-236],[164,-115],[85,-373],[411,-782],[122,-118],[-18,-251],[453,-696]],[[86468,55146],[-251,16],[-95,171],[-391,-9],[-82,234],[-157,-76],[-914,-304],[31,-197],[-1134,-397],[190,-319],[-284,-176]],[[86776,55189],[-308,-43]],[[87992,49832],[163,-48],[327,144],[290,5],[128,-179],[330,146],[194,-58],[196,-194],[248,-10],[300,-153],[221,114],[261,473],[390,-74],[-98,-234],[342,-90],[386,-280],[90,-223],[-7,-358],[369,-262],[229,-64],[189,-162]],[[87670,50811],[115,-322],[249,-75],[-42,-582]],[[87369,54857],[-478,49],[-115,283]],[[92540,48325],[23,208],[-76,362],[98,195],[-328,189],[-268,393],[18,419],[-219,438],[62,106],[-82,326],[-14,464],[74,140],[-65,189],[-6,620],[-120,223],[233,82],[111,455],[-249,-47],[-121,301],[-112,-23],[-158,198],[-286,-251],[-241,202],[-202,-80],[-373,17],[-74,-164],[-91,171],[18,250],[-289,343],[-85,278],[-194,84],[-292,-12],[-298,-205],[-702,38],[-331,-95],[-182,141],[-240,306],[-110,271]],[[72660,60563],[109,261],[344,396],[376,290],[169,-199],[434,-342],[66,358]],[[72472,60509],[188,54]],[[73169,64357],[-148,-402],[-88,-494],[-151,-334],[-253,-327],[-448,-383],[-64,-133],[50,-482],[-146,-632],[-29,-313],[137,-302],[115,-74],[328,28]],[[69036,66728],[153,-306],[536,-31],[880,134],[425,-12],[636,-221],[265,-300],[349,-209],[847,-1168],[42,-258]],[[69839,68967],[-130,-536],[115,-375],[13,-246],[-264,-614],[-343,-228],[-194,-240]],[[74795,68347],[-427,-145],[-170,-205],[-135,103],[-172,-43],[-168,115],[-155,-96],[-221,47],[-207,310],[-327,-75],[-453,-29],[-350,565],[-423,-6],[-181,547],[-464,-338],[-344,-106],[-130,136],[-629,-160]],[[75293,63076],[581,626],[292,209],[106,163]],[[82078,72296],[-468,-68],[-454,-131],[-344,-188],[-320,193],[-37,-154],[-266,-260],[43,-407]],[[82347,72243],[-269,53]],[[84387,70647],[-176,554],[-403,-32],[-245,-139],[-237,402],[74,138],[-124,259],[-161,125],[-49,224],[-287,-93],[-314,14],[-118,144]],[[80700,69649],[0,93],[1023,185],[1686,434],[978,286]],[[80791,62917],[-529,350],[-262,233],[-70,171]],[[79821,61670],[471,412],[-43,267],[-177,234],[565,324],[154,10]],[[77533,59415],[320,315],[154,-75],[264,468],[386,-193],[3,659],[405,114],[-27,181],[172,137],[-110,212],[168,51],[553,386]],[[74711,61197],[922,33],[-208,-583],[151,-370],[231,-64],[234,93],[25,-123],[321,-158],[217,-13],[292,-258],[318,-63],[319,-276]],[[83758,76757],[-110,9],[-697,-165],[58,593],[-722,-170],[14,-208],[-123,-118],[-528,-244],[44,-92],[-385,-12],[-157,86],[-4,149],[-411,-47],[-64,-187],[-467,145],[-466,86],[-548,207],[-415,71],[-272,169],[-300,75],[-426,-110]],[[82347,72243],[230,325],[-119,104],[-162,332],[-75,342],[302,164],[-9,249],[224,-5],[199,179],[348,744],[-148,9],[112,383],[340,-71],[-27,456],[164,23],[-9,274],[152,394],[-111,612]],[[77779,76994],[-325,-107],[589,-640],[711,-96],[143,-141],[122,-396],[352,-324],[56,-152],[300,-171],[350,-568],[173,-179],[280,-745],[365,382],[283,-139],[79,-199],[414,169],[139,-33],[-238,-415],[263,-306],[410,-194],[-119,-129],[-48,-315]],[[71671,73692],[-366,41],[-182,105],[-170,374],[188,559],[-61,271],[-229,207],[-263,81],[-106,157],[-47,268],[-485,428]],[[70325,73353],[135,-398],[266,-436],[45,-194],[-103,-216],[-498,-563],[-145,-378],[-180,-296],[-181,-82],[-626,231],[-258,-63],[-143,-163],[45,-217],[410,-295],[192,-205],[527,-932],[28,-179]],[[69950,76183],[44,-484],[80,-301],[4,-585],[101,-207],[142,-527],[4,-726]],[[82817,60088],[281,-557],[402,-356],[462,-106],[-18,-132],[128,-275],[119,17],[106,-307],[-48,-185],[235,-113]],[[85098,62049],[-217,-264],[76,-303],[-264,-160],[-291,130],[-360,-536],[-187,-134],[-227,62],[-145,-61],[-172,-501],[-136,41],[-358,-235]],[[86945,61256],[-298,246],[-277,99],[-461,27],[-553,320],[-258,101]],[[84484,58074],[84,-39],[242,271],[147,62],[330,282],[183,38],[202,-92],[71,471],[-57,15],[51,444],[97,48],[-5,295],[268,73],[-184,201],[206,445],[141,-116],[337,229],[204,251],[-10,142],[154,162]],[[81997,54325],[146,-346],[-422,-204],[-363,-114],[-236,-207],[251,-292],[402,-185],[-136,-125],[-148,144],[-265,-245],[258,-418],[-335,-251],[-133,-258],[-302,-334],[-656,-471]],[[83381,54089],[-242,304],[-214,-114],[-207,232],[-314,-118],[-63,160],[-363,-142],[19,-86]],[[82787,49599],[50,132],[-104,490],[441,176],[520,-723],[202,156],[92,-96],[478,146],[367,-326],[494,350]],[[79824,49820],[139,-315],[383,-256],[260,-91],[566,-48],[429,92],[681,373],[304,91],[201,-67]],[[80058,51019],[33,-143],[-298,-658],[31,-398]],[[72232,55548],[83,343],[-348,10],[-80,333],[68,337],[-172,16],[-345,-92],[-28,281],[89,319],[-480,194],[82,456],[-567,52],[113,1002],[-142,332]],[[70018,54644],[575,129],[162,-11],[748,216],[83,-94],[204,283],[177,-17],[201,177],[64,221]],[[67686,56786],[180,-335],[104,-4],[468,-542],[-57,-260],[136,-85],[111,89],[106,-147],[167,41],[339,-80],[143,-122],[401,-567],[234,-130]],[[70174,59655],[-251,-335],[-782,-806],[-518,-809],[-213,-526],[-273,40],[-90,-233],[-361,-200]],[[70505,59131],[-80,4],[-85,277],[-4,257],[-162,-14]],[[77504,57045],[-89,86],[369,411],[-47,122],[-597,560],[168,212],[407,-509],[128,66],[-70,448],[-127,343],[-212,150],[385,256],[-286,225]],[[76706,56453],[249,55],[419,354],[130,183]],[[74542,55806],[398,-257],[246,125],[391,312],[-86,221],[700,79],[232,-7],[283,174]],[[72660,60563],[643,-120],[377,-219],[93,-234],[32,-439],[87,-227],[24,-477],[-244,-551],[150,-30],[-5,-286],[83,-181],[365,-264],[-171,-204],[277,-360],[183,-334],[166,-151],[-178,-680]],[[83798,63657],[-269,363],[-104,361],[58,531],[-174,403],[-287,212],[-401,506],[-220,211],[-415,-9],[-991,-620],[-227,-103],[-248,47],[-82,230],[105,219],[224,238],[-65,342],[-408,158]],[[85098,62049],[-223,137],[-485,502],[-398,602],[-194,367]],[[80791,62917],[188,-20],[-36,-437],[50,-223],[190,-129],[273,-339],[175,-117],[495,-474],[-58,-52],[456,-552],[293,-486]],[[79735,56543],[418,-81],[284,223],[191,-58],[149,187],[251,123]],[[77504,57045],[221,-811],[260,-365],[573,476],[-218,363],[106,81],[-30,196],[96,125],[448,-121],[361,35],[146,-82],[268,-399]],[[81028,56937],[176,437],[-344,441],[-354,114],[-145,167],[55,125],[-284,387],[143,134],[-62,218],[227,146],[-430,453],[-206,278],[-310,531],[425,104],[40,251],[158,280],[-296,667]],[[84465,57857],[19,217]],[[81028,56937],[88,-79],[176,113],[141,-69],[929,570],[193,89],[486,81],[90,-179],[181,91],[63,-113],[697,245],[393,171]],[[76036,77856],[20,-252],[-49,-562],[-177,-462],[-98,-533],[-160,-303],[-30,110],[-292,-133],[-74,-202],[32,-248],[-108,-379],[-150,-108],[-314,-713],[396,-204],[-180,-527],[-344,-639],[-199,10],[-191,-165]],[[76338,78095],[-245,-78],[-57,-161]],[[77239,77308],[-217,-83],[-152,325],[-214,187],[-125,430],[-193,-72]],[[77779,76994],[-31,121],[-283,56],[-226,137]],[[86468,55146],[-107,315],[7,204],[-179,-33],[24,566],[-177,432],[-307,64],[-385,-322],[-267,195],[-147,460],[77,46],[1,292],[-176,114],[-292,70],[-75,308]],[[79735,56543],[-172,-112],[92,-200],[835,-38],[195,-168],[278,67],[335,-552],[-104,-79],[161,-285],[-54,-35],[195,-261],[351,-632],[150,77]],[[88935,61086],[-83,333],[-348,218],[-140,-10],[-473,-396],[-483,-196],[-242,10],[-221,211]],[[87369,54857],[448,46],[219,-364],[218,536],[203,108],[747,213],[419,-492],[367,235],[90,263],[256,301],[-365,386],[-102,216],[-9,241],[84,224],[474,649],[-491,364],[270,368],[508,-339],[517,714],[105,347],[-57,283],[-389,550],[-146,263],[-47,249],[-587,21],[-421,193],[-272,31],[-288,137],[-125,158],[-60,328]],[[78269,54174],[309,-179],[136,-242],[112,-534],[304,-180],[518,31],[289,-156],[12,-895],[47,-554],[-39,-225],[101,-221]],[[76706,56453],[374,-482],[87,-536],[473,-752],[188,-199],[441,-310]],[[76036,77856],[-218,-28],[-178,210],[-369,257],[-424,164],[-213,216],[-162,15],[-71,146],[-659,98],[-347,-40],[-508,59],[-555,-52],[-466,-98],[-447,112],[-118,-51],[-223,94],[-51,-128],[-176,76],[-583,0],[-498,-139]],[[69962,76570],[-12,-387]],[[69770,78767],[49,-483],[-102,-762],[245,-952]],[[87291,71149],[-477,-151],[-770,-49],[-455,-124],[-366,-29],[-300,-81],[-70,55],[-466,-123]],[[87649,68116],[9,272],[274,134],[30,191],[-220,110],[212,168],[490,-54],[488,216],[-241,769],[62,684],[6,478],[-128,209],[-1340,-144]],[[83798,63657],[292,418],[289,154],[284,417],[-52,46],[807,897],[-318,376],[365,123],[290,268],[457,283],[-202,38],[-21,110],[203,255],[187,661],[305,39],[477,-146],[90,-258],[291,314],[107,464]],[[72472,60509],[-84,-301],[-105,11],[-170,-388],[-115,-99],[-148,62],[-641,-233],[-704,-430]],[[73998,54578],[203,91],[144,279],[-281,299],[98,193],[380,366]],[[72232,55548],[509,-157],[161,-471],[276,-25],[636,-308],[184,-9]],[[69137,83542],[-424,-529],[-81,-409],[24,-373],[111,-673],[302,-776],[118,-423],[410,-882],[173,-710]],[[69317,84265],[71,-241],[-104,-297],[-147,-185]],[[73646,84905],[-397,-58],[-640,-2],[-177,-126],[-332,-44],[-808,174],[-442,-86],[-200,41],[-783,-786],[-105,-57],[-170,296],[-275,8]],[[73811,84258],[-165,647]],[[76338,78095],[-73,286],[-151,-76],[-181,487],[-600,230],[-89,-184],[-153,336],[-354,347],[-214,307],[-64,192],[-228,207],[-88,484],[217,245],[25,361],[123,50],[277,575],[-175,179],[-117,281],[-296,371],[-273,257],[21,426],[-95,171],[121,74],[-265,492],[105,65]],[[88935,61086],[323,332],[507,-216],[25,115],[246,-81],[285,634],[-1,163],[-138,104],[57,240],[-94,313],[-249,118],[-46,758],[-94,460],[154,25],[-60,459],[533,121],[123,102],[-147,425],[-166,646],[-191,16],[-40,274],[-324,-32],[-130,237],[-54,377],[-153,65],[-674,-72],[-98,390],[-153,148],[-203,332],[-16,401],[-278,181],[-23,-99],[-207,94]],[[97541,56076],[285,203],[-72,102],[-249,-200],[36,-105]],[[84684,77593],[-343,34],[-389,-463],[137,-226],[-111,-130],[-100,87],[-120,-138]],[[86949,77212],[-100,250],[-444,-301],[-269,204],[-651,-78],[-642,324],[-159,-18]],[[87291,71149],[-182,1012],[3,580],[76,410],[-106,185],[-119,780],[-90,191],[-291,282],[590,544],[22,226],[-416,-75],[-125,47],[-162,304],[193,414],[15,379],[311,312],[-109,218],[48,254]],[[97502,36914],[-230,-43],[-345,73],[102,155],[18,480],[-152,-47],[-190,278],[129,393],[69,-5],[67,446],[-224,126],[133,148],[127,316]],[[96505,33988],[109,225],[180,620],[-125,126],[-81,293],[230,119],[159,183],[-26,595],[520,550],[31,215]],[[94940,36038],[66,-129],[170,201],[145,-252],[283,-343],[188,-425],[84,-350],[308,-462],[321,-290]],[[93963,38400],[331,-188],[140,-248],[-408,-212],[-57,-272],[-132,14],[-322,-437],[159,-382],[696,117],[576,-655],[-6,-99]],[[93755,39690],[-67,-116],[68,-229],[-205,-59],[151,-309],[246,93],[248,-534],[-233,-136]],[[94287,39645],[-132,40],[-103,197],[-297,-192]],[[97006,39234],[-201,22],[-246,169],[-248,-160],[-353,-46],[-543,-209],[-250,-149],[-369,-60],[-145,370],[-275,26],[-107,150],[18,298]],[[86913,46134],[131,-534],[92,29],[156,-275],[831,-785],[390,-483],[-87,-78],[-103,-334],[110,-181],[345,-263],[192,-404],[148,-189],[-19,-211],[145,-231]],[[87950,47034],[-93,150],[-181,-57],[-327,-491],[-436,-502]],[[93170,47002],[-316,-168],[9,-131],[-596,-296],[-76,-464],[-252,-50],[-593,40],[-46,183],[-401,-127],[-658,8],[-25,139],[-652,28],[-55,-114],[-374,143],[-100,-31],[-274,182],[-600,249],[-211,441]],[[93447,44474],[208,347],[120,320],[-244,73],[-17,329],[-81,196],[48,383],[-152,634],[-159,246]],[[89244,42195],[512,437],[178,-138],[86,69],[165,-140],[184,203],[91,-19],[450,267],[-138,87],[153,137],[272,83],[103,129],[343,81],[165,-65],[-5,192],[357,204],[570,212],[230,145],[219,470],[268,-75]],[[84601,37859],[104,-40],[543,94],[378,266],[276,12]],[[81799,40916],[5,-98],[249,106],[417,-379],[451,-225],[-79,-153],[413,-278],[239,-485],[411,-639],[262,-302],[76,44],[358,-648]],[[81707,42538],[230,-479],[-267,-234],[220,-306],[-107,-65],[104,-393],[-88,-145]],[[79208,45847],[706,-560],[205,-388],[296,-319],[148,-82],[97,-287],[354,-413],[136,-372],[263,-209],[294,-679]],[[82871,47604],[-68,-387],[-122,-164],[-162,152],[20,264],[-191,106],[-100,178],[-389,-80],[86,-383],[-185,-133],[-222,107],[-265,-389],[220,-290],[-113,-195],[-251,-153],[-40,-322],[-132,-82],[-414,220],[-112,165],[-396,201],[-178,172],[-467,-187],[-147,-214],[-35,-343]],[[85340,46828],[-213,-31],[106,-275],[27,-514],[168,-307],[-245,-142],[-240,611],[-231,290],[-466,418],[-310,127],[-170,164],[-92,381],[124,632],[-123,310],[-198,70],[-304,-163],[-77,-208],[-58,-473],[-167,-114]],[[85781,40565],[-672,588],[-464,180],[-463,338],[515,468],[343,122],[198,187],[32,274],[498,200],[-58,168],[248,151],[-125,189],[137,279],[188,153],[-297,463],[85,24],[-95,426],[154,232],[31,326],[-193,116],[-103,275],[62,39],[-158,238],[67,59],[-170,247],[-91,371],[-110,150]],[[87706,39701],[-308,179],[-305,43],[-408,-56],[-220,80],[-106,189],[-578,429]],[[85902,38191],[222,66],[224,166],[-110,287],[448,211],[630,66],[390,714]],[[74449,37596],[309,458],[211,69],[286,-179],[283,322],[222,126],[231,-40],[311,144],[377,-414],[153,-243],[-64,-64],[97,-414],[339,129],[-86,233],[270,204],[-178,272],[90,153]],[[73184,38440],[143,-89],[278,7],[221,-136],[623,-626]],[[74453,41423],[-476,-292],[-20,-153],[-272,-400],[-150,99],[-273,-37],[-46,134],[-126,-159],[170,-385],[-294,-206],[351,-261],[-293,-237],[149,-129],[-161,-107],[-174,-291],[179,-54],[167,-505]],[[75719,40499],[-135,171],[-132,-114],[-775,659],[-82,169],[-142,39]],[[77300,38352],[156,166],[-206,48],[-157,173],[-201,6],[-35,206],[-446,350],[109,126],[-336,170],[35,91],[-315,135],[91,86],[-154,188],[58,97],[-180,305]],[[69177,52846],[297,-367],[-54,-110],[-272,-14],[132,-131],[-163,-107],[185,-323],[57,-451],[-24,-211],[184,-294],[172,-96],[-152,-228],[188,-313],[71,-248]],[[69957,53618],[-432,-360],[-82,-269],[-266,-143]],[[74238,48613],[-111,484],[-382,520],[-325,163],[-226,-46],[-318,103],[-97,-64],[-354,286],[67,71],[-353,473],[48,69],[-252,380],[-210,24],[-18,178],[-370,-7],[-388,697],[-82,-49],[-290,426],[114,40],[-336,443],[222,181],[-109,132],[-235,55],[124,205],[-175,222],[-225,19]],[[72360,47790],[131,291],[528,-387],[291,289],[-52,267],[225,130],[-102,161],[376,340],[481,-268]],[[69798,49953],[563,-1277],[295,159],[342,-52],[101,-402],[146,-3],[115,-186],[4,-218],[810,-595],[186,411]],[[85340,46828],[54,-3]],[[82787,49599],[109,-190],[-135,-333],[-367,-294],[-95,-302],[22,-598],[219,-291],[331,13]],[[85394,46825],[-51,344],[-234,261],[-82,259],[335,288],[-77,164],[446,18],[-54,371],[275,115],[-107,169],[-41,322],[209,69]],[[79824,49820],[-478,-47],[-96,-53],[168,-442],[-613,-503],[159,-311],[-221,-198],[166,-220],[361,-783],[-225,-202],[-279,-114],[-674,-647]],[[78092,46300],[97,-194],[92,131],[306,76],[142,-95],[189,50],[228,-467],[62,46]],[[76298,51489],[-27,330],[-368,151],[-72,446],[-161,-47],[54,272],[-347,239],[-283,855],[-115,157],[-229,-136],[-125,123],[92,87],[-211,174],[-77,-98],[-102,227],[-292,158],[-37,151]],[[75981,48730],[143,193],[302,179],[-259,590],[56,321],[-111,281],[-267,51],[47,380],[164,182],[211,33],[127,385],[-96,164]],[[74238,48613],[362,131],[568,56],[487,122],[29,-139],[297,-53]],[[70018,54644],[9,-196],[138,-301],[-60,-289],[-148,-240]],[[89349,33927],[96,-465],[97,-214],[232,-264],[619,-485],[407,-381],[355,-507]],[[90121,34790],[-89,-58],[89,-386],[-509,-141],[3,-107],[-266,-171]],[[94940,36038],[-162,-130],[-22,-196],[-266,-90],[-105,-127],[-434,54],[-105,-325],[-225,60],[-154,176],[-298,-335],[-259,257],[-201,-192],[-271,-141],[66,-93],[-170,-108],[81,-192],[-376,-198],[-197,521],[-444,-97],[-89,-296],[-223,-38],[-71,186],[-575,-109],[-51,245],[-268,-80]],[[91155,31611],[367,212],[179,-21],[616,-617],[576,339],[340,269],[-68,203],[376,132],[863,135],[335,188],[237,-7],[245,183],[13,150],[165,65],[-48,168],[223,266],[500,325],[511,289],[-80,98]],[[75981,48730],[-67,-222],[31,-316],[115,-379],[276,-213],[-91,-212],[260,-501],[339,189],[334,348],[251,-311],[463,-382],[200,-431]],[[78269,54174],[-424,-615],[-175,-104],[168,-372],[-718,-313],[74,-266],[-139,-63],[-272,-402],[-312,-120],[-38,-285],[-135,-145]],[[93963,38400],[-233,-203],[-105,-192],[-435,-380],[-35,-103],[-323,334],[-203,-128],[-516,-120],[-208,148],[-505,10],[-323,79],[46,-109],[-327,-33],[131,-339],[-244,-96],[83,-297],[-104,-47],[96,-201],[-225,-87],[119,-475],[-275,-125],[-125,-508],[-161,-76],[-133,142]],[[89958,35594],[4,-207],[-102,-76],[261,-521]],[[94287,39645],[109,33],[70,412],[367,649],[-121,394],[66,294],[-219,-62],[-143,248],[-231,36],[-201,411],[-438,275],[-138,306],[46,201],[-239,235],[-146,287],[226,473],[20,469],[132,168]],[[88955,41273],[272,-402],[224,-511],[112,-160],[172,129],[42,-220],[275,-247],[160,139],[509,-367],[117,111],[222,-346],[356,133],[714,3],[237,-211],[252,127],[35,-132],[230,78],[176,-33],[250,234],[344,209],[101,-117]],[[89244,42195],[-411,-189],[-87,-188],[209,-545]],[[87992,49832],[-75,-547],[-118,-154],[167,-6],[115,-153],[175,-26],[-50,-269],[132,-359],[-12,-356],[-138,-78],[84,-118],[-238,-185],[85,-178],[-63,-271],[-106,-98]],[[93170,47002],[186,390],[247,145],[-153,442],[98,203],[-110,95],[-546,-55],[-150,133],[-202,-30]],[[69279,36172],[320,-119],[805,-1101]],[[70240,39067],[-62,-325],[-46,-607],[-105,-385],[-60,16],[-273,-373],[-131,-662],[-229,-560],[-55,1]],[[73184,38440],[-167,-89],[-329,282],[-254,59],[-226,214],[-33,-103],[-284,46],[-83,-90],[-815,230],[-470,-12],[-283,90]],[[76344,34174],[-149,535],[-278,-38],[-98,294],[89,30],[-340,264],[69,182],[-451,444],[-255,495],[-437,445],[32,300],[164,226],[-241,245]],[[76648,32682],[-375,892],[-61,391],[132,209]],[[73100,33000],[537,-246],[114,314],[118,-73],[208,134],[329,64],[10,95],[911,186],[-14,-143],[232,-118],[264,-302],[140,-422],[234,2],[144,110],[321,81]],[[70404,34952],[718,-473],[24,-465],[87,-131],[310,28],[12,-212],[179,25],[7,-126],[241,-38],[186,-295],[506,56],[16,-210],[210,39],[-11,112],[211,-262]],[[77470,38204],[-170,148]],[[76344,34174],[-20,678],[359,-28],[76,-151],[-60,-488],[72,-6],[58,-328],[119,43],[-77,175],[73,512],[0,410],[519,220],[153,150],[-224,423],[-52,283],[-16,662],[-224,364],[487,121],[134,181],[-251,809]],[[87706,39701],[1102,-946],[249,-435],[-40,-573],[100,-484],[401,-584],[416,186],[162,-292],[-45,-126],[96,-205],[-130,-364],[-115,-96],[56,-188]],[[88955,41273],[-231,-263],[-324,-126],[-145,104],[-177,-323],[-76,-280],[-950,85],[-31,-40],[-341,236],[-269,-111],[-211,53],[-242,171],[-177,-214]],[[74453,41423],[-645,655],[196,69],[-183,218],[-211,463],[147,150],[-254,390],[377,201],[-549,704],[190,162],[-243,307],[274,267],[349,589],[-1227,1394],[279,303],[-593,495]],[[67211,42843],[210,-426],[174,-201],[528,-44],[212,-373],[213,-177],[342,-171],[403,-274],[325,-442],[146,-289],[18,-521],[556,-706],[-98,-152]],[[69292,49449],[320,-245],[-120,-102],[235,-202],[-204,-149],[239,-330],[136,-38],[214,-585],[-163,-57],[531,-862],[-317,-156],[17,-108],[-220,-76],[93,-271],[-469,-85],[-229,-143],[-61,-193],[197,-307],[92,51],[167,-302],[-172,-153],[-224,53],[-229,-159],[89,-200],[260,-322],[-278,-203],[-317,-727],[-162,-211],[-516,255],[-345,-5],[-645,-774]],[[69798,49953],[-483,-212],[104,-220],[-127,-72]],[[85394,46825],[162,-83],[175,-325],[283,0],[291,-129],[231,109],[209,-323],[168,60]],[[75719,40499],[313,237],[-136,173],[154,162],[154,-181],[317,209],[559,-28],[168,-192],[765,561],[-93,127],[249,159],[148,-164],[399,343],[70,-38],[322,219],[-169,229],[177,82],[276,404],[-93,82],[122,208],[401,-425],[266,-122],[158,-178],[258,108],[239,-152],[285,244],[550,-67],[129,39]],[[97502,36914],[295,-3],[392,143],[-113,418],[250,112],[455,343],[108,324],[138,80],[199,298],[-76,190],[178,260],[-196,93],[518,573],[-118,89],[288,525],[179,507],[-135,137],[-152,-313],[-265,73],[-13,-212],[-134,-440],[-483,-147],[-253,-184],[-110,56],[-192,-376],[-201,45],[-185,-126],[-334,-68],[-259,-299],[-277,222]],[[55300,59552],[-266,1],[-642,-139],[-223,2],[-30,124],[-465,-147]],[[60194,57624],[-763,679],[-603,340],[-362,355],[-557,69],[-119,72],[-574,29],[-369,-92],[-72,54],[-391,-132],[-294,105],[-357,-105],[-252,375],[-181,179]],[[59398,57243],[399,101],[397,280]],[[52592,56571],[332,-47],[1426,-267],[417,-35],[620,72],[4011,949]],[[53674,59393],[-522,-111],[-194,-227],[-535,-159],[-598,-51]],[[69320,59773],[321,719],[-49,878],[292,-63],[-45,506],[139,-17],[-436,709]],[[66495,58978],[145,545],[257,-27],[399,-193],[174,94],[-122,174],[346,30],[47,-345],[124,-325],[130,68],[335,-181],[327,160],[479,308],[-119,379],[303,108]],[[63848,59574],[786,-129],[650,-224],[1211,-243]],[[69542,62505],[-210,320],[-378,-63],[-1745,-194],[-1290,-480],[-282,-233],[-264,300],[-667,-344],[142,-267],[-92,-148],[-281,-173],[-258,-463],[-406,-327],[78,-64],[46,-346],[-87,-449]],[[70673,63413],[181,-256],[-294,-217],[-407,-38],[28,-60],[-374,-71],[126,-196],[-391,-70]],[[73169,64357],[-256,115],[-461,-228],[-316,-246],[-88,-533],[-203,-92],[-41,122],[-293,55],[5,105],[-389,2],[-454,-244]],[[69320,59773],[228,-118],[355,273],[275,360],[199,-262],[-203,-371]],[[66051,73205],[286,-378],[5,-107],[-1073,-402],[-277,-284],[-596,-187],[23,-70],[-688,-217],[-186,29],[-236,-209],[-508,-175]],[[69585,76409],[95,-423],[-280,-417],[-154,86],[-396,-132],[-131,-347],[1,-221],[-433,-417],[-276,866],[-164,-260],[188,-457],[65,-273],[-361,-189],[-113,-228],[-335,-225],[-679,594],[-354,-399],[448,-431],[-655,-331]],[[69962,76570],[-377,-161]],[[65568,69148],[-158,290],[585,304],[-194,266],[413,357],[232,-144],[486,490],[-211,278],[156,247],[-79,59],[399,143],[158,292],[-138,361],[411,197],[412,147],[313,26],[700,-154],[200,17],[251,203],[446,454],[173,70],[202,302]],[[65256,68957],[312,191]],[[62152,65307],[-467,-167],[16,625],[149,201],[-350,58],[109,546],[111,265],[181,168],[204,-147],[150,44],[117,313],[-125,258],[169,253],[797,228],[269,15],[928,158],[307,273],[180,249],[359,310]],[[61763,62722],[34,310],[134,146],[190,435],[-152,573],[-150,223],[23,117],[-221,250],[230,114],[301,417]],[[60745,62908],[493,-168],[51,131],[474,-149]],[[60357,66542],[141,-916],[-15,-843],[98,-407],[82,-1061],[82,-407]],[[62391,70924],[-37,-539],[263,-675],[379,325],[326,425],[232,162],[207,45],[580,-328],[152,-28],[53,-509],[-34,-295],[-116,-205],[-325,-358],[-386,-115],[-541,121],[-298,-74],[-517,-482],[-160,-513],[-114,-210],[-1435,-223],[-232,-388],[-31,-518]],[[62801,71205],[-462,-146],[52,-135]],[[62152,65307],[30,210],[355,-17],[60,281],[123,178],[534,6],[33,-143],[347,-3],[11,-156],[233,-141],[268,4],[79,-529],[282,-108],[391,117]],[[64898,65006],[-498,629],[-52,656],[505,858],[50,157],[354,327],[203,810],[-19,195],[-185,319]],[[68369,66589],[-353,139],[37,235],[-339,139],[131,186],[286,40],[35,215],[-120,172],[-366,179],[-416,83],[-363,135],[-18,265],[-119,292],[-281,441],[-447,202],[-468,-164]],[[68677,65754],[-58,338],[-278,214],[28,283]],[[64898,65006],[308,559],[265,190],[448,-175],[210,-318],[158,-92],[594,191],[122,108],[498,-67],[559,-146],[106,410],[511,88]],[[61763,62722],[-143,-394],[97,-206],[261,-243],[-18,-448],[265,-216],[296,-36],[434,-238],[46,-520],[461,-374],[-65,-380]],[[70673,63413],[-401,568],[-519,-451],[-402,476],[-223,-249],[-297,351],[-256,147],[135,733],[213,-39],[45,381],[-416,-87],[125,511]],[[63397,59667],[451,-93]],[[66309,84471],[-143,128],[-115,669],[-190,171],[92,340],[-44,233],[70,281],[-125,326],[36,281],[91,8]],[[62611,82811],[94,295],[598,86],[1009,323],[472,286],[331,302],[369,147],[406,78],[419,143]],[[62323,88134],[-246,-292],[-353,-868],[-31,-189],[-133,-21],[-296,-238],[-98,-189],[119,-242],[20,-300],[153,-128],[4,-409],[-89,-239],[25,-171],[300,-474],[-107,-252],[81,-80],[-81,-263],[292,-319],[-322,-240],[86,-198],[192,44],[35,134],[210,-41],[141,-218],[386,-130]],[[65981,86908],[-76,574],[-236,478],[-69,-57],[-417,-677],[-491,131],[-778,-95],[-201,-92],[-429,628],[-602,586],[-359,-250]],[[58987,77249],[-58,248],[111,27],[218,-178],[567,98],[-106,156],[-445,354],[-340,339],[-349,555],[-166,427],[160,-82],[189,171],[-211,124],[75,212],[191,-51],[102,147],[-113,245],[137,202]],[[55656,76824],[317,-95],[450,40],[766,-102],[850,187],[461,-62],[487,457]],[[53480,78413],[174,-238],[303,-108],[600,-308],[204,7],[280,-185],[81,-146],[319,-236],[215,-375]],[[54782,79808],[-96,-233],[-67,-710],[68,-291],[-39,-190],[-154,204],[-104,-45],[-294,131],[-426,-104],[-190,-157]],[[58949,80243],[-1014,-133],[-161,-55],[-106,-199],[-577,-349],[-683,34],[-301,104],[-264,-13],[-114,233],[-290,9],[-50,369],[-167,-33],[68,-199],[-212,79],[13,-166],[-309,-116]],[[69036,66728],[-667,-139]],[[59722,80946],[4,-211],[-493,-154],[-284,-338]],[[62057,81731],[-1006,-156],[-480,-171],[-214,18],[-428,-230],[-207,-246]],[[66541,77763],[-56,371],[-361,116],[324,431],[-612,185],[-754,-208],[-241,135],[-200,-93],[-233,260],[-178,52],[-226,346],[-36,383],[-95,242],[-221,173],[-457,64],[-134,-171],[-155,0],[-467,602],[-211,-49],[-179,-164],[-323,131],[-197,199],[-185,-88],[-278,22],[-302,213],[755,386],[560,136],[-22,294]],[[64196,76200],[176,6],[446,-184],[34,187],[344,-64],[121,728],[31,507],[312,-14],[38,70],[330,-203],[162,509],[351,21]],[[62982,75429],[220,517],[300,338],[694,-84]],[[58987,77249],[157,-286],[246,-137],[32,-322],[103,-99],[357,311],[51,-139],[271,19],[330,-136],[841,335],[425,245],[422,32],[41,-325],[615,117],[-223,-427],[-31,-365],[-130,-440],[253,-208],[235,5]],[[66051,73205],[-836,1673],[-80,208],[-825,1050],[-114,64]],[[62982,75429],[107,-160],[-215,-236],[-298,-123],[-309,-47],[-469,-228],[-315,-316],[-176,-283],[-180,-537],[-362,-443],[-26,-225],[916,-127],[81,-255],[-175,-185],[-421,-191],[686,-252],[386,30],[157,-118],[113,87],[419,92],[109,-122],[-266,-456],[57,-129]],[[69585,76409],[-133,343],[16,643],[-457,-98],[-240,103],[-343,-63],[-928,409],[-198,27],[-761,-10]],[[52023,66015],[-103,185],[-253,69],[-299,-84],[-242,-171],[-166,-231]],[[53674,59393],[-22,459],[184,94],[-56,716],[76,236],[141,77],[52,217],[-63,282],[129,-18],[53,320],[128,10],[-11,428],[-57,193],[-389,511],[-60,251],[-263,607],[-132,458],[43,512],[82,132],[-77,179],[-435,157],[-573,-46],[-267,352],[9,245],[-143,250]],[[60194,57624],[232,445],[48,265],[-33,498]],[[60745,62908],[-710,49],[-22,83],[-445,-55],[-297,-99],[10,-86],[-471,108],[-821,-168],[-843,-74],[-226,-100],[-175,-930],[-296,-713],[-548,-623],[-128,-556],[-394,-87],[-79,-105]],[[60441,58832],[-3,919],[-84,373],[6,965],[280,714],[146,540],[-41,565]],[[62611,82811],[25,-363],[-131,-19],[222,-334],[-12,-113],[-486,-225],[-172,-26]],[[69137,83542],[-678,463],[-34,92],[-368,18],[-377,171],[-258,197],[-67,-89],[-245,209],[-524,44],[-277,-176]],[[57206,68061],[283,126],[279,13],[317,-126],[159,-139],[103,-416],[1331,-180],[-22,-97],[351,58],[-144,-256],[2,-493],[492,-9]],[[62391,70924],[-1308,-400],[-963,-124],[53,-267],[-485,23],[-145,182],[-291,52],[-349,452],[-877,110],[-243,-466],[-392,-337],[-530,-528],[138,-201],[-270,-343],[40,-261],[-128,-140],[165,-176],[240,-54],[203,-202],[-43,-183]],[[54398,66490],[627,603],[447,266],[259,295],[140,67],[460,55],[97,407],[98,148],[350,-277],[330,7]],[[52737,69836],[52,-109],[421,-234],[162,-160],[119,-275],[158,-88],[148,-263],[-7,-143],[224,33],[-148,-128],[215,-174],[-138,-244],[42,-138],[-157,-137],[46,-195],[135,66],[143,-426],[152,-304],[94,-427]],[[55656,76824],[142,-495],[158,-161],[46,-696],[240,-281],[-129,-9],[-69,-272],[106,-41],[-20,-221],[-485,-153],[-28,-367],[240,-195],[-77,-219],[127,-47],[-194,-829],[-156,-27],[-55,-330],[112,-213],[-50,-196],[-243,-29],[81,-165],[-212,-155],[-80,-229],[-178,-23],[-215,159],[-79,-73],[-290,162],[-28,-194],[-259,-121],[50,-131],[-415,-103],[2,-154],[-275,-338],[-49,-143],[-13,-673],[-624,-26]],[[54398,66490],[-241,-270],[-528,-281],[-715,-160],[-59,261],[-832,-25]],[[66716,22983],[151,-504]],[[64907,29104],[-229,-225],[102,-459],[186,-315],[126,-665],[106,37],[-145,-554],[10,-216],[-134,-113],[96,-193],[3,-334],[277,-18],[95,-394],[-228,-381],[481,-77],[78,173],[126,-66],[376,-573],[70,-308],[-113,-31],[54,-221],[156,-134],[65,-447],[208,-248],[43,-359]],[[67986,29221],[-1555,403],[-213,-7],[-30,-227],[-613,-185],[-545,-32],[-123,-69]],[[68932,25273],[-946,3948]],[[66867,22479],[634,515],[711,423],[257,77],[463,1779]],[[66562,35172],[-1212,-983],[-80,-215],[69,-381],[5,-404],[-60,-209],[-243,-50],[-100,311],[-288,585],[-192,54]],[[67986,29221],[-1424,5951]],[[63308,30307],[149,-32],[646,52],[46,-291],[244,46],[83,-419],[232,34],[159,-361],[40,-232]],[[63126,32673],[-235,-522],[-53,-379],[52,-392],[131,-219],[60,-299],[235,-396],[-8,-159]],[[64461,33880],[-292,28],[-281,-145],[-65,-168],[114,-329],[-246,-128],[-128,163],[-26,-439],[-111,-145],[-300,-44]],[[58423,40051],[56,-244],[169,-276],[-47,-344],[-395,-766],[-217,-244],[-206,-123],[-22,-123],[-175,3],[-322,-342],[30,-406],[-415,120],[-604,-42]],[[60872,39526],[-179,229],[-369,-93],[-153,96],[-87,244],[-165,-86],[-297,305],[-127,-170],[-645,92],[-427,-92]],[[62005,38019],[-207,479],[-168,114],[-532,738],[-226,176]],[[62224,37368],[-72,171],[-322,437],[175,43]],[[59922,33378],[260,283],[180,287],[86,9],[-53,240],[157,449],[-71,4],[83,443],[310,470],[197,91],[-79,96],[270,227],[-189,336],[407,379],[200,114],[295,500],[249,62]],[[59463,33738],[44,-221],[181,-302],[234,163]],[[56521,36274],[33,37],[456,-117],[171,107],[263,-29],[150,-161],[366,-100],[191,-185],[-62,-49],[328,-334],[258,-458],[289,-159],[209,-4],[93,-176],[39,-411],[158,-497]],[[56275,37264],[-36,-206],[285,-205],[23,-176],[-179,-299],[153,-104]],[[58086,22378],[-9,403],[108,363],[339,280],[-306,372],[215,115],[424,74],[192,-95],[360,-43],[246,192],[329,2],[-65,178],[-257,337],[152,110],[-168,243],[326,297],[592,411],[2,55],[805,331],[-89,271],[-321,352],[159,171],[-54,101]],[[56342,21544],[196,124],[33,307],[427,260],[243,84],[845,59]],[[55545,29123],[228,-68],[-121,-203],[17,-510],[256,-270],[96,-261],[170,-217],[-59,-106],[176,-199],[-257,-166],[-214,-412],[18,-219],[-427,49],[-131,-114],[-347,-34],[-174,-470],[242,-346],[567,-496],[117,-163],[-11,-392],[-127,-270],[100,-124],[254,-91],[-5,-255],[331,-448],[-187,-278],[231,-169],[206,-378],[-60,-247],[12,-492],[-104,-230]],[[57452,30915],[-266,-117],[-588,-525],[-59,51],[-321,-375],[-404,-165],[-476,-348],[207,-313]],[[60068,28281],[-918,947],[4,597],[-236,228],[-348,42],[-446,223],[-73,96],[140,264],[-82,87],[-455,-36],[-202,186]],[[61066,26898],[-120,137],[152,183],[-1030,1063]],[[43572,34882],[233,112],[110,355],[525,705],[-55,602],[-117,303],[213,156],[94,-71]],[[42314,35514],[61,-322],[682,-191],[379,26],[136,-145]],[[44411,39454],[-750,78],[-532,23],[-441,-418],[50,-679],[-34,-396],[-373,-221],[-225,-196],[-288,-646],[-90,-433],[376,-351],[54,-525],[156,-176]],[[62890,29351],[-327,-24],[-341,-132],[-77,-392],[-362,-94],[-204,148],[-211,-296],[-369,-49],[-204,195],[-262,-214],[-158,136],[-307,-348]],[[61066,26898],[169,179],[268,-277],[193,184],[110,-125],[257,264],[132,8],[-176,149],[322,310],[-154,211],[439,268],[-49,154],[534,298],[-17,72],[285,74],[-167,318],[-322,366]],[[59922,33378],[240,-213],[366,-40],[182,116],[297,-180],[410,-857],[147,40],[131,298],[286,174],[208,-154],[264,74],[404,-41],[269,78]],[[64461,33880],[-286,585],[-20,183],[-405,631],[-261,273],[-178,-146],[-237,314],[-11,234],[-109,430],[-302,216],[-428,768]],[[66716,22983],[-543,-29],[-436,-264],[-5,115],[-201,-104],[-857,-127],[-371,-85],[-319,-164],[-477,-12],[-365,-242]],[[63142,22071],[-292,-161],[-104,-338],[-144,-181],[2,-368],[-128,-89],[-543,8],[-183,366],[-229,-213],[-865,-73],[-452,-117],[-316,-140],[2,-333],[454,1],[349,-338],[32,-159],[-279,-199],[-39,-244],[146,-312],[159,-80],[200,-293],[158,-36],[137,-272],[256,138],[74,-174],[280,-117],[266,103],[42,-139],[236,5],[-165,-324],[-10,-187],[208,-74],[230,-573],[486,68],[119,115],[571,-73],[197,59],[466,369],[482,113],[-24,229],[128,58],[489,-1],[509,-78],[492,28],[-131,259],[9,552],[-197,22],[74,296],[27,986],[208,37],[-47,345],[129,49],[-68,304],[55,348],[-168,254],[170,375],[279,378],[-12,229]],[[54251,29520],[484,-175],[472,-299],[338,77]],[[51441,34082],[-206,-105],[139,-475],[363,-212],[88,101],[233,-167],[273,17],[-120,-160],[40,-369],[422,-289],[256,12],[203,129],[128,-394],[-302,-265],[-228,-356],[600,-358],[237,-358],[119,-48],[304,-481],[-55,-148],[93,-351],[223,-285]],[[56521,36274],[-107,-150],[58,-221],[-282,-60],[-697,-385],[-228,-73],[-118,-243],[-811,-388],[-1039,-390],[-266,118],[-575,-277],[-524,-93],[-491,-30]],[[57452,30915],[266,429],[230,226],[-281,335],[386,193],[320,14],[187,162],[88,277],[200,214],[429,622],[-42,113],[228,238]],[[63308,30307],[3,-138],[199,-355],[-101,-125],[-1,-299],[-518,-39]],[[58086,22378],[538,51],[550,194],[751,206],[223,-119],[44,198],[147,18],[115,-203],[92,228],[469,35],[211,167],[456,103],[332,302],[143,-24],[273,180],[80,-258],[139,-100],[151,90],[251,-320],[168,-674],[-77,-381]],[[47057,31903],[207,-148],[-11,-347],[288,-207],[181,-358]],[[50269,34033],[-268,-160],[-657,-79],[-279,-417],[-305,-103],[-384,-11],[-312,47],[-198,-173],[-416,-547],[89,-134],[-187,-77],[-63,-274],[-232,-202]],[[51441,34082],[-105,123],[-142,-148],[-428,-99],[-148,-220],[-177,76],[-37,247],[-135,-28]],[[51105,27039],[205,335],[-43,401],[286,486],[186,89],[114,-61],[286,97],[133,194],[398,16],[273,123],[-32,92],[200,139],[104,393],[115,-106],[292,289],[2,100],[348,-68],[-25,-194],[140,-79],[164,235]],[[47722,30843],[255,235],[249,-376],[18,-291],[117,-430],[206,-281],[224,-93],[1019,390],[180,-80],[181,59],[147,222],[516,-226],[-199,-341],[65,-385],[282,-533],[54,-269],[-187,-264],[129,-130],[-111,-331],[63,-475],[175,-205]],[[50723,25548],[859,-363],[560,-183],[185,-256],[104,-317],[202,-279],[488,-816],[-17,-558],[289,-754],[166,-252],[940,-66],[476,-64],[620,-447],[137,-57],[610,408]],[[50547,25814],[176,-266]],[[51105,27039],[-622,-748],[273,-417],[-209,-60]],[[50269,34033],[-177,677],[-275,529]],[[42927,32804],[710,-193],[397,-73],[43,-157],[205,-10],[210,373],[359,13],[250,-313],[316,-272],[45,249],[192,45],[251,-88],[386,211],[368,-532],[334,-197],[64,43]],[[43572,34882],[-191,-362],[-112,-486],[-19,-311],[-106,-341],[-207,-418],[-10,-160]],[[53737,40296],[-209,-266],[168,-141],[-115,-389],[181,1],[11,-601],[228,-15],[79,-300],[189,69],[511,-266],[29,-571],[262,-302],[100,-246],[171,-59],[354,43],[579,11]],[[58423,40051],[-310,425],[-146,35]],[[39503,85961],[-13,9]],[[39516,81915],[-37,377],[37,388],[-43,339],[-36,774],[9,472],[76,570],[-19,1126]],[[38203,79456],[226,370],[258,224],[77,152],[29,405],[329,275],[87,493],[231,282],[-36,172],[112,86]],[[36243,79324],[145,251],[14,283],[216,186],[175,316],[208,-9],[265,-128],[320,-258],[85,-227],[532,-282]],[[34355,80232],[74,-243],[204,13],[-19,-271],[351,12],[-49,-228],[224,-74],[489,9],[327,-55],[206,47],[81,-118]],[[34612,84666],[14,-960],[135,-61],[-51,-302],[114,-141],[-175,-438],[75,-355],[-144,-280],[-63,-392],[-21,-1128],[-141,-377]],[[39490,85970],[-4,-481],[-884,-269],[-610,-255],[-193,-734],[-325,32],[-164,115],[-819,-51],[-4,223],[-356,49],[-480,-10],[-6,331],[-736,-15],[-1,-156],[-288,-5],[-8,-78]],[[36243,79324],[-58,-480],[-90,-124],[-309,-140],[55,-322],[159,-137],[69,71],[192,-108],[-64,-85],[99,-213],[-171,-95],[-409,-647],[-126,-118],[106,-186],[-146,-215]],[[43309,79102],[-449,63],[-362,-398],[-345,-121],[-39,-119],[-309,-17],[-108,-631],[-267,-152],[43,-264],[-941,217],[-42,-134],[-369,616],[-206,-159],[-62,85],[-239,-192],[-20,237],[-181,-112],[-329,-4],[-159,109],[33,315],[-87,248],[-9,517],[-178,69],[-190,-55],[-291,236]],[[44437,77557],[-114,-46],[-376,490],[-116,393],[-173,158],[-349,550]],[[43672,74416],[-181,249],[100,238],[-38,442],[143,415],[428,-141],[8,132],[481,47],[-287,170],[-96,460],[94,-36],[266,240],[-16,143],[122,352],[-259,430]],[[41953,72198],[780,856],[158,67],[110,339],[226,-81],[41,172],[233,-10],[-85,634],[198,-19],[-63,162],[121,98]],[[35550,76525],[592,-412],[428,24],[755,-298],[462,83],[207,-66],[475,46],[167,-166],[365,112],[162,-62],[233,144],[143,-82],[171,-302],[145,19],[-51,-421],[87,-289],[238,-318],[234,-107],[138,-166],[402,-190],[277,-337],[304,-288],[254,-792],[-41,-116],[256,-343]],[[53505,86210],[-88,-333],[-240,-405],[72,-250],[-20,-623],[314,-509],[22,-162],[-314,-282],[329,-86],[-20,-558],[-263,-143],[59,-191],[-105,-192],[173,65],[22,-256],[-250,-145],[-72,-222],[263,-599],[152,-36],[159,-424],[100,-627],[463,-75],[-70,-356],[348,-53],[243,60]],[[59722,80946],[-29,419],[-267,166],[-383,414],[66,103],[-441,267],[113,429],[164,58],[-232,377],[-179,491],[-95,533],[13,351],[-276,11],[-155,298],[-185,90],[-59,-86],[-627,226],[-63,147],[-183,-167],[-153,39],[-31,-222],[-255,15],[-6,200],[-621,-26],[-501,36],[-282,179],[-563,76],[-265,166],[30,73],[-335,154],[-417,447]],[[41115,69201],[-422,237],[-148,561],[67,241],[464,524],[359,-257],[124,213],[8,751],[525,559],[-139,168]],[[37808,70909],[220,-158],[205,-43],[-49,-356],[198,-220],[184,137],[152,-230],[143,-3],[210,-192],[-43,-142],[172,-428],[209,-388],[162,-190],[365,-218],[291,260],[-155,203],[251,383],[105,63],[256,-141],[431,-45]],[[31707,72784],[650,404],[707,178],[167,1],[625,-154],[313,-284],[669,-140],[408,37],[268,-38],[408,32],[-3,73],[303,8],[273,107],[18,-118],[818,-588],[77,-162],[144,25],[222,215],[234,-331],[-304,-507],[-2,-351],[113,-72],[-7,-210]],[[35550,76525],[-176,-277],[-219,-148],[16,-136],[-354,-367],[-265,-394],[87,-116],[-307,-31],[23,-307],[-76,-178],[-332,-121],[-580,-15],[-555,-239],[-671,-698],[-283,-392],[-151,-322]],[[49690,78548],[50,131],[-277,182],[-287,681],[11,164],[-268,98],[-97,426],[99,207],[-122,15],[101,345],[-106,205],[-189,135],[416,331],[271,-16],[-215,234],[-216,479],[128,428],[-12,501],[-210,585],[92,580],[-323,297],[-70,185],[-252,119],[-717,-122],[-139,167],[-212,-14],[-166,186],[-195,27],[-245,149],[-487,578],[-98,61],[-262,-390],[-335,265],[-214,-98],[-139,200],[-274,-64],[-152,355]],[[44437,77557],[589,193],[421,-402],[220,-612],[380,-415],[246,115],[148,-33],[-41,187],[194,155],[-35,402],[368,595],[516,-131],[407,-1],[268,72],[354,-105],[570,88],[341,-13],[-180,361],[296,181],[-76,332],[267,22]],[[39516,81915],[261,-21],[382,164],[356,79],[475,40],[-40,-133],[625,-519],[486,-556],[57,-205],[194,123],[291,-155],[137,8],[239,-536],[209,-166],[153,-600],[-32,-336]],[[44579,86160],[-839,-387],[-655,-174],[-875,-131],[-368,-125],[-350,-194],[-316,-40],[-395,57],[-406,126],[-476,307],[-396,362]],[[51411,87365],[-572,-434],[-340,-186],[-248,-68],[-522,-14],[-311,61],[-440,255],[-366,324],[-338,371],[-316,250],[-467,167],[-263,-64],[-289,-180],[-192,-22],[-294,88],[-116,-46],[-272,-469],[-572,-488],[-315,-229],[-350,-386],[-249,-135]],[[53505,86210],[-150,143],[-47,294],[-346,272],[-781,-82],[14,70],[-364,237],[-38,97],[-272,-9],[-110,133]],[[49690,78548],[176,15],[450,370],[154,-138],[304,-75],[575,143],[1197,-354],[934,-96]],[[31939,81262],[355,121],[221,-20],[76,-192],[-237,-199],[-106,-458],[202,-92],[89,-171]],[[33499,85029],[-117,-678],[-155,-287],[165,-17],[-142,-591],[193,-75],[-87,-249],[-154,-139],[-612,-168],[-28,-214],[-202,-7],[-131,-908],[-290,-434]],[[34612,84666],[-461,25],[51,300],[-703,38]],[[32539,80251],[273,-25],[140,326],[369,81],[1034,-401]],[[42560,64677],[-205,-250],[-232,-114],[-163,26],[-310,-170],[-38,210],[-228,198],[-357,495],[-879,389],[-166,-237],[-252,-63],[-150,305],[-166,-102],[-32,-335],[-176,319],[-209,-116],[71,-140],[-427,12],[-76,140],[-227,-171],[82,-60],[-91,-192],[-268,-115],[-319,-34],[-94,64],[-436,-35],[15,-283],[155,-240],[239,-47],[295,-149],[-175,-178],[-203,-55],[-237,-242],[-536,84],[-626,-124]],[[36139,63467],[77,-315],[166,-306],[59,-604],[-62,-597],[188,-662],[164,-310],[-111,-204],[226,-391],[28,-234]],[[59698,92305],[-338,818],[42,87],[-141,348],[10,168],[186,486],[145,-72],[98,123]],[[55270,92060],[315,-350],[243,-56],[411,-456],[300,241],[193,-346],[197,-511],[330,-7],[139,-112],[1054,719],[299,573],[464,402],[141,-48],[342,196]],[[59700,94263],[-380,152],[-391,230],[-408,80],[-191,-40],[-370,-218],[-397,-424],[-609,-463],[-162,-325],[85,-555],[-92,-355],[-366,-246],[-1149,-39]],[[33676,86468],[-98,-665],[-79,-774]],[[39490,85970],[-223,130],[-645,192],[-437,69],[-505,-21],[-1407,-248],[-387,-25],[-623,15],[-638,70],[-641,179],[-308,137]],[[35043,66242],[76,64],[-328,478],[441,131],[405,281],[210,293],[-9,152],[172,-7],[5,134],[-306,195],[90,230],[392,-3],[481,95],[-49,338],[-164,277],[59,230],[62,611],[252,-32],[96,299],[423,-102],[21,398],[185,-16],[141,-147],[26,395],[84,373]],[[31333,71504],[58,-52],[-300,-666],[-26,-284],[57,-653],[-81,-227],[-33,-423],[-127,-347],[-85,-867],[-96,-191],[-110,-731],[-109,-361],[728,279],[38,-89],[418,183],[146,-188],[1036,-902],[-190,-574],[91,-106],[208,25],[131,-110],[193,154],[-40,441],[318,414],[172,-18],[188,162],[207,416],[186,102],[26,-129],[389,-323],[317,-197]],[[31707,72784],[-181,-428],[-60,-422],[-133,-430]],[[35043,66242],[117,-148],[155,-478],[84,-578],[-223,-382],[527,-461],[247,-175],[189,-553]],[[42424,66777],[-124,495],[-336,75],[-3,95],[-343,70],[-294,871],[-72,329],[44,194],[-181,295]],[[52737,69836],[-386,67],[107,-406],[239,-353],[-137,-115],[-183,84],[-474,394],[-216,263],[275,137],[-151,302],[-172,175],[-317,182],[11,91],[-314,83],[-60,188],[-156,90],[-261,3],[-83,115],[-256,-130],[-370,466],[-251,0],[-185,378],[-398,53],[-181,515],[-199,90],[-153,-368],[-265,-69],[87,-223],[365,-522],[-152,-162],[-106,73],[-699,-319]],[[47696,70918],[69,-310],[284,-336],[44,133],[180,-55],[93,-194],[371,-372],[293,-384],[-268,-11],[12,-165],[-190,-376],[-236,-641],[-7,-343],[159,-243]],[[55270,92060],[-977,113],[-586,-28],[-303,-73],[-321,-190],[-381,-410],[-284,-420],[-241,-547],[-54,-355],[-34,-934],[-124,-823],[-206,-568],[-348,-460]],[[61888,89659],[-163,234],[-15,198],[-345,582],[-199,136],[-272,57],[-326,234],[190,471],[91,370],[-261,10],[-139,256],[-279,225],[-472,-127]],[[62323,88134],[-60,420],[-194,465],[-181,640]],[[43672,74416],[309,-200],[39,-113],[320,-84],[297,-164],[133,42],[183,-150],[210,-438],[510,-9],[189,96],[185,-505],[-101,-119],[159,-326],[448,-520],[217,144],[248,-237],[40,70],[370,-225],[-200,-166],[28,-126],[205,-77],[235,-391]],[[66039,49115],[-372,-201],[-700,-581],[-219,-250],[-122,-573],[-253,-107],[-82,-503],[88,-334],[-177,-225]],[[68645,48884],[-259,227],[-363,139],[-364,-42],[-158,230],[-248,-97],[-841,24],[-213,-335],[-160,85]],[[66513,45825],[364,466],[241,-234],[244,-14],[448,389],[-202,499],[129,280],[-91,209],[293,429],[210,221],[150,430],[346,384]],[[64202,46341],[452,-122],[227,-194],[556,83],[175,-693],[800,241],[101,169]],[[64140,37425],[-147,12],[-130,-311],[-306,-151],[-126,287],[1,-339],[-494,-282],[-184,421],[-383,621],[-366,336]],[[66562,35172],[-835,1502],[-88,418],[-116,77],[-36,435],[-357,203],[-937,-448],[-53,66]],[[66865,57145],[119,-37],[405,81],[258,-58],[39,-345]],[[66495,58978],[129,-35],[249,-617],[152,-173],[141,-662],[-354,-50],[53,-296]],[[66513,45825],[117,-210],[133,-686],[191,-352],[370,-387],[117,-450],[-230,-897]],[[69292,49449],[-72,43],[-411,-301],[-164,-307]],[[63270,41318],[237,137],[411,-186],[346,270],[386,168],[181,166],[209,-272],[210,193],[6,204],[-132,271],[111,58],[299,-307],[319,218],[-116,147],[765,388],[386,101],[323,-31]],[[61908,46924],[-131,-354],[181,-199],[37,-357],[160,-325],[-14,-157],[-327,-281],[-10,-452],[-105,-218],[-184,-109],[299,-515],[256,-696],[94,39],[658,-1156],[448,-826]],[[64202,46341],[-615,23],[-352,156],[-383,43],[-563,188],[-381,173]],[[73652,30816],[25,13],[-298,1049],[175,-33],[-85,462],[-304,69],[-65,624]],[[68932,25273],[686,2642],[320,111],[290,-7],[213,-216],[260,-44],[784,-48],[-172,436],[-26,323],[222,54],[-61,511],[153,184],[231,28],[-66,214],[543,98],[34,263],[120,78],[-122,331],[263,146],[-27,198],[253,94],[80,-74],[273,24],[469,197]],[[70404,34952],[-297,-271],[-193,-55],[156,-348],[264,-318],[213,-689],[-152,-101],[99,-418],[-65,-23],[167,-489],[18,-321],[112,-589],[42,-748],[69,-685],[-85,-626],[-457,-293],[-142,-139],[-336,32],[-278,-44],[-1553,394]],[[62547,40933],[-20,-43],[-786,-460],[-12,-101],[-338,-260],[-280,-317],[-188,-87],[-51,-139]],[[64140,37425],[8,334],[-276,599],[-155,574],[311,258],[-591,573],[-211,294],[-287,236],[-392,640]],[[65508,52756],[240,-1120],[239,-342],[130,-408],[-1,-424],[-77,-1347]],[[69177,52846],[-620,-401],[-132,152],[-218,-289],[-90,158],[-248,-36],[-39,210],[-672,-178],[-26,128],[-209,-41],[-13,103],[-487,-168],[-14,113],[-286,-117],[-302,206],[-313,70]],[[60441,58832],[1083,-395],[328,337],[308,623],[229,383],[532,-90],[476,-23]],[[56945,52306],[-223,26],[-212,186],[-242,66],[-113,-258],[-777,-200],[12,214],[-367,-10],[-9,59],[-632,-23],[-156,-49]],[[55281,48293],[129,114],[16,222],[-149,287],[193,-151],[153,56],[490,528],[85,280],[595,311],[160,258],[162,114],[-15,273],[-222,86],[126,1204],[-101,339],[42,92]],[[58993,54604],[-262,-260],[-325,-152],[-296,-68],[121,-319],[-32,-263]],[[62631,55856],[102,-454],[269,-13],[113,-377],[762,-789],[389,-762],[-325,-13],[-1189,-241],[-619,-40],[-73,67],[-469,-38],[-43,274],[-717,-66],[-19,126],[-286,27],[-22,422],[59,249],[-538,120],[-137,115],[-570,193],[-325,-52]],[[65530,54896],[-763,272],[-283,197],[-574,135],[-318,123],[-518,280],[-443,-47]],[[65508,52756],[-276,432],[25,164],[172,227],[40,407],[-46,366],[127,205],[-76,236],[56,103]],[[60352,46858],[838,143],[362,-6],[356,-71]],[[58199,53542],[252,-385],[529,-393],[138,-622],[296,-564],[353,33],[211,-50],[49,-299],[474,89],[641,15],[-3,64],[500,5],[80,-66],[-115,-736],[273,2],[-10,-110],[237,-35],[-303,-585],[-46,-641],[-259,-860],[-553,-1019],[-333,-364],[-258,-163]],[[69279,36172],[-78,-131],[-673,431],[-399,-394],[-135,-31],[-119,163],[-189,-123],[-1124,-915]],[[65530,54896],[126,714],[-6,147],[216,473],[670,558],[329,357]],[[59618,56153],[830,148],[206,126],[170,252],[-21,135],[286,113],[336,-21],[158,-359],[195,73],[115,-361],[176,-56],[10,-292],[178,-2],[-2,-140],[376,87]],[[59398,57243],[220,-1090]],[[59618,56153],[-325,-245],[-172,-61],[-62,-227],[221,-475],[-28,-242],[-237,-163],[-22,-136]],[[58000,53173],[199,369]],[[56945,52306],[231,598],[824,269]],[[58952,47415],[-185,891],[-95,171],[158,31],[-34,347],[826,175],[-42,493],[-206,-19],[-48,528],[4,516],[-337,-11],[-24,362],[-125,14],[-12,432],[102,18],[-170,250],[-289,552],[-191,640],[-284,368]],[[57087,45061],[241,-139],[323,8],[386,122],[111,94],[26,271],[195,445],[61,460],[-133,316],[554,239],[101,538]],[[63270,41318],[-723,-385]],[[60352,46858],[-452,97],[-30,302],[-307,19],[-611,139]],[[87350,3925],[249,465],[43,404],[112,120],[-275,-12],[-176,196],[538,401],[278,122],[92,202],[111,496],[-198,48],[211,760],[210,-77],[59,262],[-196,79],[161,322],[-169,-2],[84,696],[-535,-28],[31,746],[-195,19],[120,687],[-615,-130],[-104,195],[-485,-146],[-177,-158],[-261,15],[-19,85],[-498,-29],[-141,-237],[-206,65],[-221,-144],[-82,119],[-354,124]],[[84742,9590],[-173,-48],[137,-482],[-31,-712],[123,-390],[237,-255],[-43,-285],[425,-151],[37,-306],[291,-321],[-53,-208],[178,-117],[-113,-155],[138,-24],[219,-314],[-200,-305],[250,-77],[293,-262],[345,-511],[146,-363],[402,-379]],[[83962,32894],[412,-667],[327,-869],[273,380],[176,-200],[167,0],[268,272],[245,-79],[-61,-292],[115,79],[-135,-464],[405,-96],[420,48],[-19,-347],[-219,-303],[122,-292],[-32,-482],[111,-272],[121,40],[-44,220],[120,15],[173,-583],[-171,-30],[133,-292],[457,-251],[153,-256]],[[84696,34171],[-261,-226],[-25,-149],[192,-255],[-708,-537],[68,-110]],[[86448,35191],[-88,-1],[-46,-328],[-397,-460],[-301,222],[-48,-142],[-317,-313],[-254,330],[-301,-328]],[[89349,33927],[-50,456],[-256,73],[-232,-98],[-394,-67],[-267,70],[-39,-295],[-138,-27],[-47,424],[-311,-76],[-271,126],[-128,381],[-385,-35],[-68,329],[-153,-71],[-162,74]],[[91564,30883],[-172,388],[-237,340]],[[87479,28173],[7,425],[240,205],[438,-2],[910,419],[8,-118],[445,22],[1029,244],[265,304],[165,432],[250,251],[154,404],[174,124]],[[89309,20077],[-427,-183],[9,-228],[-363,-21],[-60,125],[-401,-108],[-89,141],[-445,147],[-299,-23],[68,-705],[-161,-390],[105,-332],[-52,-149],[-220,-39],[29,-269],[130,-203],[63,-593],[-43,-293],[-277,59],[-141,-63],[-724,-90],[78,-708],[-60,-223],[-390,-61],[-263,-109],[91,-95],[-196,-147],[-382,-571],[-350,-129],[-234,-217],[-271,144],[-204,9],[-605,286],[-155,36]],[[90940,16844],[-30,143],[-280,-1],[-145,408],[-288,-161],[-195,96],[-210,1056],[0,813],[-184,469],[-299,410]],[[83462,13328],[300,27],[395,-137],[284,43],[126,-76],[361,37],[631,460],[177,30],[221,-109],[494,-76],[363,58],[-4,-118],[277,-8],[55,580],[234,-1],[371,-94],[204,-353],[299,-38],[557,14],[145,102],[382,-837],[116,-34],[102,301],[-87,401],[359,5],[-14,318],[538,-31],[65,681],[323,-3],[126,74],[-133,577],[-135,915],[443,-100],[74,278],[-161,402],[-10,228]],[[83070,15075],[24,-482],[168,-67],[-88,-398],[71,-376],[217,-424]],[[86189,22426],[-569,-83],[-673,-10],[-124,-247],[45,-101],[-272,-156],[-619,38],[-217,256],[-352,67],[29,143],[-363,-55],[-303,87],[27,-115],[-194,-89],[80,-398],[-828,-459],[-212,119],[-139,-84],[56,-165],[-241,-117]],[[89119,20640],[1,290],[-221,789],[-311,-155],[-816,-66],[-151,159],[-88,-644],[-114,-139],[-250,-41],[-27,172],[-579,14],[5,323],[-133,212],[-53,475],[-190,-164],[-3,561]],[[89309,20077],[-121,241],[-69,322]],[[81320,21057],[-26,-324],[-87,-188],[34,-454],[154,-438],[72,-748],[111,-192],[89,-346],[-23,-366],[131,-79],[19,-216],[360,-351],[-89,-448],[18,-219],[-185,-330],[99,-294],[777,-179],[174,-761],[122,-49]],[[86448,35191],[71,269],[-138,231],[-65,382],[19,595],[62,544],[-227,508],[-152,141],[-116,330]],[[84286,34711],[410,-540]],[[84601,37859],[-446,211],[-290,-253],[232,-416],[-263,-736],[143,-186],[-148,-305],[181,-239],[243,-472],[364,-471],[-331,-281]],[[77004,32032],[-356,650]],[[79107,28257],[2,143],[-206,281],[-215,38],[-185,506],[95,169],[-179,72],[78,206],[-151,-26],[-277,485],[-166,-12],[-204,360],[-101,336],[-138,43],[-310,589],[-146,585]],[[78976,27725],[94,113],[37,419]],[[73652,30816],[104,-62],[209,-524],[104,-374],[114,113],[29,-156],[339,49],[728,190],[119,-523],[297,-44],[289,171],[364,138],[122,-236],[241,10],[21,-88],[528,-117],[210,-145],[372,-375],[313,-498],[208,-166],[332,-378],[281,-76]],[[79107,28257],[129,148],[-88,416],[81,68],[356,-278],[110,-220],[369,-117],[-51,260],[583,379],[12,189],[194,12],[302,297]],[[77887,38530],[109,46],[245,-88],[224,-216],[111,93],[215,-358],[-2,-340],[160,-219],[55,-337],[104,-248],[69,-380],[-194,-178],[151,-271],[215,-641],[-453,-257],[-70,-164],[-120,66],[80,-573],[-382,11],[45,-165],[-216,-152],[-305,-53],[-286,-341],[-235,-32],[100,-339],[-199,-141],[151,-788],[-292,-199],[-163,-234]],[[79203,38523],[-230,336],[-256,-137],[-178,77],[-536,610],[-256,-192],[-169,-310],[290,-281],[19,-96]],[[84286,34711],[-57,63],[-476,-106],[-282,373],[-614,-378],[-243,323],[-192,-173],[-206,5],[-221,-155],[-98,363],[-205,-138],[-453,-131],[-315,430],[256,306],[-271,436],[567,466],[-852,1291],[-267,-172],[-223,537],[-289,-181],[-217,544],[-308,-156],[-117,265]],[[81104,29411],[165,97],[59,-95],[315,61],[-5,237],[454,299],[105,157],[-108,449],[346,331],[-174,289],[441,417],[194,-52],[148,382],[140,-96],[200,303],[293,297],[285,407]],[[81799,40916],[-291,-253],[3,-193],[-223,-164],[-368,257],[-175,-241],[-461,-118],[30,-169],[-267,-58],[145,-894],[-989,-560]],[[82186,24988],[58,183],[127,797],[315,617],[74,216],[-421,-171],[-481,513],[69,56],[-146,401],[-272,-44],[59,330],[-130,-6],[-125,465],[-136,241],[9,644],[-82,181]],[[80193,23331],[139,137],[479,279],[184,-6],[388,230],[215,44],[55,198],[-109,343],[350,112],[-30,-156],[322,476]],[[78976,27725],[309,-104],[-217,-409],[-205,-113],[-350,-713],[117,-400],[110,-875],[160,-402],[311,-510],[236,-563],[74,59],[213,-186],[213,159],[246,-337]],[[90658,4800],[-107,-473],[239,28],[-128,-496],[89,-21],[42,-523],[-110,119],[-169,-149],[-88,-354],[-227,-525],[-329,-3],[-279,-304],[-74,-303],[125,-124],[303,9],[-207,-306],[-97,-272]],[[94971,4147],[-448,-138],[-36,-182],[-787,-80],[-24,-208],[-407,-207],[-468,-91],[-93,742],[109,332],[-116,96],[-362,2],[-350,-111],[-318,265],[-23,239],[-406,-27],[-3,190],[-158,14],[-259,-216],[-164,33]],[[89641,1103],[156,-420],[23,-365],[239,92],[309,-89],[277,162],[241,-42],[332,32],[359,-115],[130,83],[458,-249],[347,105],[218,-232],[79,37],[813,52],[150,-154],[482,235],[261,205],[322,443],[145,374],[70,561],[-40,328],[-325,911],[-55,346],[42,223],[297,521]],[[80193,23331],[205,-302],[298,-572],[192,-217],[297,-914],[135,-269]],[[86154,22600],[-23,124],[-246,-6],[-4,106],[-535,-34],[-135,339],[-272,317],[27,229],[-171,55],[27,292],[-143,13],[-21,275],[-109,-199],[-450,-83],[-698,-327],[-251,63],[-31,388],[-89,73],[-152,-130],[-161,439],[-128,558],[-271,-168],[-132,64]],[[86189,22426],[-35,174]],[[77887,38530],[-105,-399],[-83,180],[-229,-107]],[[89119,20640],[303,232],[-251,509],[179,170],[213,31],[32,275],[-83,99],[301,-39],[-39,197],[148,41],[-72,219],[509,190],[-155,335],[127,74],[268,-39],[189,76],[213,-477],[671,384],[20,-246],[251,-292],[222,55],[421,204],[209,-339],[25,-220],[112,94],[847,29],[-66,-231],[186,-192]],[[87479,28173],[-14,-364],[73,-429],[239,-662],[-15,-743],[-515,-579],[-235,-945],[-315,-95],[97,-633],[-90,-76],[85,-286],[-84,-211],[-212,-129],[-339,-421]],[[93899,21779],[267,417],[103,337],[-94,430],[-418,594],[-454,478],[-169,364],[15,335],[215,613],[-39,314],[-104,200],[-349,396],[-55,340],[222,964],[-9,387],[-194,329],[-591,588],[-204,280],[-118,327],[-153,776],[-206,635]],[[90940,16844],[217,58],[37,-128],[349,-40],[840,359]],[[92383,17093],[-219,1050],[9,373],[259,746],[223,331],[788,788],[159,202],[83,331],[50,587],[164,278]],[[92981,9553],[-294,34],[-212,-335],[-154,-88],[-33,-666],[-72,-508],[-287,-355],[-385,182],[-194,-175],[-440,2],[-376,-251],[-7,-287],[-179,-93],[117,-809],[-223,-544],[-85,-496],[-127,-187],[-21,-201],[289,49],[360,-25]],[[94971,4147],[94,376],[7,833],[-61,473],[-412,1525],[-120,265],[-256,241],[-210,83],[-593,125],[-160,133],[-279,1352]],[[87350,3925],[42,-726],[200,11],[121,-226],[210,-1267],[253,-46],[315,-218],[149,52],[127,-157],[874,-245]],[[83462,13328],[-23,-793],[140,-403],[316,-608],[94,-252],[350,-385],[250,-400],[-7,-478],[199,13],[-39,-432]],[[92981,9553],[-6,380],[118,747],[183,430],[235,384],[110,305],[9,282],[-73,278],[-315,746],[-61,251],[-85,779],[-145,551],[-9,285],[67,858],[-65,367],[-202,328],[-227,250],[-132,319]],[[28953,79303],[-171,-15],[-385,-414],[-167,-92],[-49,-199],[-411,-331],[-394,-10],[-359,-247],[-263,46],[-208,-146],[-23,121],[-345,252],[-446,72],[-244,-116],[-260,-13],[-250,-212],[-149,-37],[-195,-556],[27,-602],[-72,-913],[-98,-390],[-68,214],[-154,13]],[[30896,77322],[-498,236],[225,394],[-350,173],[-782,831],[-25,527],[-513,-180]],[[30703,76948],[193,374]],[[25710,72926],[248,242],[507,389],[952,351],[240,179],[171,32],[-2,247],[118,62],[814,801],[292,35],[-138,401],[551,194],[-128,76],[646,-28],[-1,201],[520,763],[203,77]],[[24269,75728],[53,-645],[510,-288],[-11,-292],[186,-751],[703,-826]],[[5596,84050],[-230,-227],[-178,-85],[-645,-171],[-518,-84],[-2309,-254],[-849,-122],[-222,-80],[-645,-381],[183,-640],[243,-165],[367,105],[190,-209],[67,172],[127,-47],[113,198],[168,-92],[56,-201],[131,-81],[11,-306],[178,-119],[191,74],[182,-183],[441,76],[257,-522],[-8,-138],[392,-464],[1054,-328],[199,62],[232,-213],[215,105]],[[6626,82955],[-441,-107],[-189,-147],[-81,152],[142,113],[-315,581],[184,58],[-218,164],[79,75],[-191,206]],[[4989,79730],[-73,44],[412,122],[306,197],[144,240],[465,179],[-113,306],[138,666],[-193,386],[469,187],[-159,306],[314,-69],[11,272],[-84,389]],[[11464,74234],[145,-169]],[[11390,74347],[74,-113]],[[10604,75238],[786,-891]],[[10270,75521],[334,-283]],[[9874,81642],[-272,-528],[-266,-897],[462,-118],[296,-370],[330,14],[398,-194],[281,-611],[-144,-17],[132,-377],[168,-240],[-107,-58],[181,-553],[-236,-425],[-68,-379],[-341,-649],[-445,-589],[27,-130]],[[14034,81734],[-261,-81],[-183,151],[-7,251],[-167,262],[-586,212],[-254,0],[-480,226],[-268,-136],[-218,4],[193,-283],[-462,-120],[-309,-380],[-141,-106],[-201,-373],[-427,-107],[-268,196],[-121,192]],[[16060,81511],[-311,-14],[-243,105],[-904,151],[-248,-37],[-66,114],[-254,-96]],[[11609,74065],[330,-218],[367,-43],[329,80],[662,919],[309,675],[116,22],[399,348],[426,439],[248,38],[-45,141],[724,937],[440,148],[6,553],[146,288],[34,757],[-14,459],[43,267],[-63,910],[129,-27],[147,327],[-282,426]],[[16569,91722],[37,-689],[123,-673],[-364,-225],[-407,-71],[344,-1384],[9,-134],[-400,-288],[394,-764],[-627,-265],[39,-107],[179,70],[212,-480],[-430,-200],[111,-1071],[-628,-35],[-41,-400],[-184,27],[-39,-355],[-549,138],[-120,-463],[-184,-249],[-30,-405],[88,-161],[182,-30],[38,-452],[-30,-239],[-189,-321],[-49,-197],[-20,-565]],[[24703,91994],[-601,532],[-378,230],[-429,139],[-389,65],[-1206,-89],[-711,70],[-255,-6],[-775,-171],[-466,-203],[-594,-464],[-929,-430],[-294,-91],[-403,-36],[-462,47],[-242,135]],[[22041,89017],[560,733],[219,-161],[340,290],[371,-225],[159,325],[153,511],[212,183],[-94,226],[154,283],[193,87],[395,725]],[[18624,81818],[307,469],[-137,400],[-68,385],[-9,1144],[-100,22],[407,544],[218,-89],[155,182],[84,286],[467,152],[-16,56],[583,261],[347,-7],[150,437],[315,499],[123,632],[126,274],[465,1552]],[[16060,81511],[476,96],[634,-99],[458,-239],[221,10],[775,539]],[[24719,83166],[350,138],[562,67],[418,-94],[322,-183],[-37,-958],[44,-384],[639,479],[252,-20]],[[24666,85407],[351,-220],[-27,-228],[-139,-73],[-402,-589],[-111,-223],[299,-481],[82,-427]],[[26162,85973],[-436,-307],[-184,296],[-600,-337],[-237,-74],[-39,-144]],[[30402,83829],[-632,357],[-402,121],[-501,34],[-538,-76],[-667,77],[-486,198],[-380,330],[-427,572],[-207,531]],[[29758,83464],[196,310],[136,-72],[312,127]],[[27269,82211],[143,252],[276,-195],[52,122],[177,-153],[355,162],[-94,137],[35,193],[167,104],[-41,101],[279,265],[540,315],[600,-50]],[[31939,81262],[-92,-56],[50,341],[-471,392],[-237,272],[-587,191],[-206,8],[-426,281],[-8,272],[-241,185],[172,275],[-135,41]],[[30896,77322],[222,458],[-106,98],[169,454],[164,-107],[50,211],[-222,120],[213,491],[153,153],[181,-65],[188,397],[202,-148],[111,169],[127,-66],[191,764]],[[27269,82211],[-30,-452],[204,-153],[223,-550],[68,-308],[159,-255],[374,-239],[256,-370],[240,-264],[190,-317]],[[9874,81642],[-64,166],[-230,241],[-513,-168],[-165,-463],[-156,83],[-136,296],[-293,12],[-347,88],[-199,314],[-143,32],[-374,-63],[-389,79],[-98,710],[-141,-14]],[[4989,79730],[252,51],[344,-85],[374,155],[86,-116],[538,-37],[149,-124],[126,38],[401,-175],[1433,-438],[398,-161],[235,-191],[406,92],[228,-101],[299,-225],[45,-627],[-332,-455],[203,-695],[-38,-754],[134,-361]],[[10604,75238],[-109,-444],[174,-184],[-224,-505],[-15,-282],[-246,-122],[-45,-270],[-171,-133],[-121,-261],[431,51],[68,146],[361,370],[185,89],[340,-80],[-12,-169],[271,126],[-150,327],[-135,18],[184,432]],[[11464,74234],[94,-285],[51,116]],[[16569,91722],[-342,510],[-312,245],[-229,85],[-767,165],[-236,15],[-466,-122],[-219,-248],[-497,-1313],[-104,-535],[-144,-1253],[-143,-439],[-213,-268],[-725,-486],[-230,-203],[-414,-487],[-358,-811],[-138,-186],[-665,-319],[-282,-223],[-267,-77],[-693,-327],[-730,-63],[-491,-116],[-649,-306],[-367,-112],[-832,-329],[-226,-153],[-234,-316]],[[30703,76948],[532,-215],[-86,-371],[158,-207],[1,-386],[173,-299],[306,-238],[19,-393],[388,-433],[-266,-954],[-107,-164],[-114,-504]],[[33676,86468],[-378,169],[-312,13],[-448,-220],[-429,-416],[-145,-315],[-87,-690],[-93,-421],[-163,-411],[-260,-364],[-318,-133],[-641,149]],[[26162,85973],[-195,900],[51,495],[459,852],[50,513],[-127,629],[-542,1177],[-327,562],[-494,595],[-334,298]],[[22041,89017],[1170,-1267],[497,-192],[152,-398],[347,-268],[-28,-157],[236,-77],[-11,-444],[138,-182],[-247,-408],[371,-217]],[[25710,72926],[15,-1507],[923,-8],[300,-193],[224,-37],[328,-219],[825,-31],[346,171],[169,-253],[499,6],[117,-135],[1225,460],[472,374],[180,-50]],[[18624,81818],[338,-231],[142,-175],[190,-11],[316,-627],[144,-359],[253,-315],[110,-684],[139,-309],[-55,-584],[737,7],[275,538],[330,215],[185,35],[174,-84]],[[21902,79234],[330,-83],[221,919],[138,129],[542,323],[132,197],[515,405],[-79,62],[104,268],[89,-6],[299,437],[337,875],[189,406]],[[21902,79234],[-84,-507],[-89,-134],[-25,-413],[48,-302],[28,-615],[315,145],[478,-748],[340,-366],[331,-126],[712,-167],[313,-273]],[[24163,36318],[369,-129],[135,-191],[1,-208],[227,-224],[233,-78],[779,-439],[500,-447]],[[27700,40400],[-944,798],[-254,366],[-23,143],[-184,13],[53,-366],[-208,-329],[-283,-300],[-315,-513],[-433,-824],[-301,-707],[-71,-662],[70,-417],[178,-262],[2,-211],[-356,-298],[-468,-513]],[[26407,34602],[413,338],[280,444],[346,224],[-272,109],[-191,291],[-260,160],[161,657],[-90,100],[-16,443],[101,2],[121,340],[538,162],[22,820],[345,-83],[423,87],[317,137],[148,-7],[131,339],[-494,-78],[-72,99],[79,202],[-348,249],[-351,21],[-169,140],[-31,341],[162,261]],[[38480,28952],[969,-1111],[-63,-364],[69,-297]],[[36833,31283],[-393,-598],[-79,-176],[-185,-79],[-261,-328],[8,-96],[292,-155],[192,-277],[278,-128],[442,-76],[96,-80],[528,215],[265,9],[147,316],[331,-283],[167,113],[166,-103],[-354,-368],[107,-114],[218,-17],[-318,-106]],[[41474,31355],[-882,632],[-990,346],[-124,-42],[-57,195],[-565,-56],[-449,41],[-200,-92],[-157,-198],[-358,-209],[-221,-209],[-74,-202],[-564,-278]],[[41506,26896],[2,531],[-331,243],[-147,277],[-85,605],[68,517],[96,395],[-397,549],[53,252],[402,214],[223,209],[84,667]],[[39455,27180],[598,-108],[1197,70],[256,-246]],[[24705,21823],[-66,-671]],[[27433,26321],[-525,-460],[-333,-159],[-434,-136],[-177,-111],[-891,-318],[-579,-404],[-298,-407],[228,-359],[-133,-197],[179,-473],[74,-455],[119,-43],[104,-247],[-74,-208],[80,-242],[-122,-151],[54,-128]],[[30773,27890],[55,-118],[-191,-282],[-238,-181],[-60,81],[-564,-541],[-501,-539],[-234,-195],[-291,-138],[21,-145],[-169,-101],[-349,131],[-531,133],[-200,407],[-88,-81]],[[32148,27873],[-387,303],[-988,-286]],[[24639,21152],[351,102],[1730,188],[551,-385],[949,-858],[552,-119],[545,-172],[567,-116],[353,431],[495,517],[305,176],[525,416],[1091,1359],[1038,894],[-39,106],[-358,342],[48,292],[-185,440],[-347,163],[-117,562],[-224,375],[-175,135],[59,394],[-154,139],[-173,385],[-74,489],[236,162],[-40,304]],[[46318,28344],[207,45],[36,-172],[169,45],[196,-337],[27,-279],[149,60],[166,-454],[250,151],[293,-14],[-63,-84],[383,-249],[565,-307],[475,-353],[681,128],[356,-87],[106,-334],[233,-289]],[[47722,30843],[-272,-80],[-56,-338],[-322,-74],[-100,-158],[-252,40],[-17,340],[-344,-70],[129,-482],[249,-419],[-265,-118],[-326,-301],[140,-272],[-111,-284],[143,-283]],[[40287,43496],[-1068,-941],[61,-388],[422,-855],[-288,-532],[-313,-166],[-239,-253]],[[40068,36403],[278,-374],[316,-265],[519,-282],[269,16],[9,-86],[340,29],[207,132],[39,-287],[292,24],[-145,159],[122,45]],[[38862,40361],[64,-87],[2,-361],[-182,-329],[-27,-220],[321,-275],[426,-256],[-81,-247],[35,-317],[320,-30],[63,-220],[352,-124],[-53,-221],[-350,-83],[-33,-735],[75,-285],[274,-168]],[[46459,23969],[289,66],[-18,199],[552,-5],[506,-424],[383,125],[163,-114],[295,91],[197,360],[419,168],[-92,153],[265,72],[-33,275],[506,152],[832,461]],[[45619,26464],[182,-600],[261,-434],[350,-1104],[47,-357]],[[46318,28344],[-306,-82],[-50,-141],[116,-147],[-78,-279],[76,-205],[-60,-167],[-524,-216],[127,-643]],[[22142,28955],[-1095,1021],[-540,-199],[-834,780],[-174,-153],[-447,392],[-276,140]],[[24705,21823],[-225,-23],[-131,-173],[-252,-41],[-205,-184],[-211,-30],[23,360],[-208,526],[-394,23],[-2243,2301],[-16,169],[386,198],[274,198],[252,91],[323,209],[453,190],[342,227],[-274,701],[-475,362],[-559,168],[-151,590],[511,777],[170,52],[47,441]],[[18776,30936],[-270,-327],[-171,-303],[-48,-273],[-178,-372],[-238,-375],[-82,-852],[-74,-276],[-238,-439],[-1157,-1374],[-526,-270],[-384,-105],[-175,-108],[75,-226],[239,10],[-42,-213],[194,-167],[-158,-172],[23,-179],[225,-30],[161,-357],[-197,-135],[123,-614],[-167,-111],[69,-130],[-347,-355],[-63,-150],[287,-421],[-319,-255],[99,-85],[-52,-291],[101,-242],[222,-271],[-21,-301],[164,101],[143,-161],[0,-179],[255,-442],[139,-24],[94,-365],[265,-151],[347,-454],[68,168],[381,21],[139,-282],[1376,-393],[236,150],[1673,872],[3672,1124]],[[29128,32768],[69,-77]],[[26407,34602],[209,-152],[374,-92],[622,1],[279,-157],[353,-590],[401,-359],[46,-94],[437,-391]],[[33845,37472],[-25,31],[-655,-187],[-379,-141],[-1052,-518],[47,200],[-108,373],[-65,485],[27,607],[96,321],[102,593],[-137,610],[-96,-38],[-1267,22],[-1590,197],[-903,91],[-140,282]],[[35584,34746],[-316,91],[-89,104],[-489,191],[-647,579],[-198,317],[-73,222],[525,231],[-38,157],[-317,222],[97,291],[-233,161],[39,160]],[[29197,32691],[368,-78],[432,-357],[136,-205],[190,58],[400,-448],[139,-82],[208,394],[519,509],[473,369],[409,256],[461,-253],[33,-82],[365,44],[110,-49],[428,252],[-134,363],[327,94],[502,31],[-1,576],[62,84],[623,448],[243,-14],[94,145]],[[42664,26736],[-108,-297],[-220,-176],[-245,-74],[-16,-168],[191,42],[63,-208],[-157,-107],[-602,-232],[-239,-189],[-304,-152],[-265,184],[-87,-68]],[[45619,26464],[-780,-94],[-283,2],[-149,-123],[76,423],[-218,186],[-819,42],[-373,172],[-409,-336]],[[40675,25291],[425,-642],[-68,-331],[101,-48],[60,-250],[-138,-151],[31,-483],[-34,-182],[64,-413],[-160,-463],[15,-742],[187,-80],[349,-28],[301,-274],[647,-177],[329,-174],[124,345],[2825,543],[42,-112],[1561,528],[-628,903],[-152,293],[-97,616]],[[24163,36318],[-188,-346],[-68,-364],[-155,-220],[-652,-54],[-648,148],[-306,32],[-418,-42],[-578,-494],[-335,-214],[-361,-133],[-255,-177],[-231,-252],[-137,-354],[-157,-698],[-375,-754],[-131,-353],[-111,-519],[-281,-588]],[[26123,32197],[323,82],[405,-34],[237,-121],[271,226],[648,-240],[346,37],[470,442],[305,179]],[[22142,28955],[65,281],[227,154],[1030,412],[372,94],[715,519],[374,365],[753,884],[227,50],[-78,312],[296,171]],[[36496,34788],[552,121],[282,342],[268,607],[183,117],[348,-103],[230,120],[306,425],[291,119],[464,-398],[165,-46],[483,311]],[[35584,34746],[504,-60],[408,102]],[[38862,40361],[-141,-19],[-625,-313],[-474,-123],[-121,42],[-210,-431],[-275,-244],[14,-189],[-278,-229],[-105,191],[-904,-527],[35,-92],[-268,-181],[59,-255],[-824,-196],[14,-62],[-803,-196],[-111,-65]],[[41506,26896],[218,-93],[335,-30],[571,204],[34,-241]],[[42927,32804],[-75,-413],[-322,-222],[-146,-225],[-321,-780],[-589,191]],[[30773,27890],[-163,342],[-359,971],[-191,451],[-192,743],[-151,377],[-266,404],[-35,175],[-2,880],[-217,458]],[[26123,32197],[88,-72],[122,-419],[144,-200],[22,-300],[156,-22],[91,-243],[-385,-1025],[47,-390],[-225,-470],[-16,-244],[240,-490],[211,-169],[499,-96],[-59,-228],[191,-56],[459,-496],[237,-383],[-512,-573]],[[36496,34788],[87,-309],[-60,-304],[124,-190],[52,-437],[139,-262],[541,-672],[-67,-390],[-183,-228],[-135,-435],[-161,-278]],[[39455,27180],[59,-391],[324,-392],[373,-667],[151,-74],[313,-365]],[[32148,27873],[723,436],[2110,-140],[243,-336],[1809,332],[1126,1156],[321,-369]],[[70692,91860],[-1153,-493],[-624,-239],[-331,-74],[-117,-475],[-72,-75],[381,-266],[-23,-273],[-333,-266],[-76,-405],[-271,-385],[88,-45],[31,-533],[138,-355],[-279,-52],[34,-443],[-168,-59],[-474,59],[-210,158],[-60,-216],[-296,-91],[-896,-424]],[[72023,90413],[-1331,1447]],[[69317,84265],[-201,462],[-423,548],[-76,464],[22,165],[224,508],[293,347],[286,207],[455,126],[480,50],[1007,242],[487,234],[230,286],[133,362],[132,544],[74,539],[-51,364],[-179,446],[-187,254]],[[73646,84905],[199,138],[33,280],[-241,265],[259,322],[-103,75],[149,355],[442,790],[-102,130],[65,298],[-66,39],[229,733],[-39,129],[422,707],[301,283],[57,544],[194,186],[57,315],[77,50]],[[75005,90989],[-315,128],[-379,49],[-729,-99],[-293,-207],[-333,91],[-58,112],[-249,-33],[-50,105],[-170,-136],[65,-182],[-221,-80],[-250,-324]],[[75579,90544],[-574,445]],[[78869,85714],[-534,398],[-580,63],[-178,86],[-224,-69],[-29,-223],[-97,23],[-339,-364],[-281,-139],[-175,277],[-605,-479],[-51,60],[-395,-437],[-89,93],[-891,-583],[-129,182],[-461,-344]],[[81604,84626],[-420,182],[-224,217],[-498,-101],[-407,159],[-149,151],[-422,-146],[-276,185],[-161,-144],[-105,105],[-211,-94],[-18,180],[183,49],[-27,345]],[[77239,77308],[135,127],[360,174],[414,74],[-120,656],[-4,564],[194,550],[191,284],[392,425],[142,374],[377,-240],[366,528],[-34,328],[329,73],[215,660],[401,268],[94,596],[-181,124],[203,26],[-107,408],[-10,276],[298,63],[173,228],[40,314],[515,181],[-18,257]],[[90918,86716],[203,-170],[331,-162],[415,-394],[119,-826],[-394,-317],[-134,-177],[-43,-250],[115,-465],[531,-1192],[412,-656]],[[90937,90705],[160,-142],[221,-537],[369,-183],[185,-186],[-118,-393],[-249,100],[-26,-282],[-170,-79],[-59,-441],[-181,-578],[356,-391],[-477,-619],[-30,-258]],[[94184,89863],[-471,258],[-574,437],[-375,236],[-768,339],[-237,55],[-378,-80],[-444,-403]],[[94542,88735],[-374,81],[-266,162],[35,455],[88,-24],[159,454]],[[92473,82107],[149,33],[65,167],[-293,654],[-129,121],[-50,405],[272,-296],[175,-39],[-28,174],[219,88],[-119,105],[157,44],[-132,310],[220,-51],[98,396],[159,80],[321,465],[192,-80],[20,114],[630,-67],[-256,377],[-20,317],[203,214],[-316,354],[-27,394],[153,376],[97,460],[173,116],[18,470],[-133,43],[207,641],[44,243]],[[63067,96633],[18,-417],[118,18],[378,-165],[663,33],[149,-147],[-171,-359],[260,-176],[-146,-171],[346,-202],[-79,-344],[192,-81],[-17,-170],[110,-421]],[[67961,98885],[-177,360],[-319,281],[-602,318],[-451,122],[-516,30],[-374,-64],[-534,-250],[-240,-194],[-440,-487],[-227,-358],[-746,-1646],[-268,-364]],[[64888,94031],[255,42],[124,237],[209,-25],[161,619],[95,168],[275,243],[237,-68],[56,352],[125,-11],[428,134],[-1,215],[171,170],[-33,250],[113,31],[-79,240],[17,303],[81,102],[-35,215],[66,213],[-109,247],[-151,113],[73,557],[342,-119],[353,407],[300,219]],[[73710,95101],[-134,-63],[-127,-258],[-230,85],[-247,279],[-268,111],[-307,42],[-181,-59],[-294,206],[-232,31],[49,-127],[-194,-253],[-194,-8],[127,-231],[-390,-105],[-492,-43],[-341,686],[-400,498],[-781,286],[-212,-408],[-107,-429],[151,-203],[-74,-126],[-207,-64],[-66,206],[-340,-116],[-249,101]],[[75005,90989],[-99,283],[158,264],[-52,218],[167,127],[-26,124],[243,138],[66,165],[-250,14],[-74,289],[-194,300],[-189,152],[-345,48],[-343,338],[390,-5],[-155,619],[-46,439],[242,522],[-129,482],[-365,-143],[-294,-262]],[[67970,95139],[122,-382],[298,-391],[2302,-2506]],[[73710,95101],[-17,372],[-174,292],[106,409],[-164,328],[-124,625],[-357,187],[-193,-61],[-665,150],[25,468],[728,539],[169,-19],[282,118]],[[68337,97122],[-350,-1464],[-17,-519]],[[73326,98509],[-118,254],[-200,109],[-567,-58],[-254,-86],[-678,-346],[-529,-118],[-581,76],[-328,-145],[-364,-586],[-445,-580],[-172,-165],[-352,-171],[-198,88],[-203,341]],[[61888,89659],[402,12],[-41,170],[125,883],[610,634],[382,287],[700,210],[-68,468],[340,327],[90,243],[131,23],[61,205],[-136,296],[69,165],[288,69],[114,199],[-67,181]],[[63067,96633],[-298,-187],[-532,-200],[-427,-256],[-351,-377],[-291,-467],[-234,-223],[-361,-466],[-258,-164],[-332,-71],[-283,41]],[[86020,84577],[-98,107],[-421,-390],[-336,-214],[-400,29],[-130,126],[-514,-25],[-66,150],[-920,-157],[-531,282],[-607,85],[-318,294],[-75,-238]],[[84684,77593],[68,255],[281,131],[-373,325],[-503,255],[29,448],[-168,341],[57,394],[171,172],[711,504],[233,357],[153,103],[-188,401],[-266,218],[-280,85],[25,427],[134,183],[328,232],[274,442],[221,97],[162,411],[-58,491],[325,712]],[[68337,97122],[-179,1091],[-197,672]],[[83607,89677],[-120,-820],[72,-270],[-190,-214],[-132,-452],[111,-753],[250,-142],[504,-167],[538,-346],[278,-228],[387,-201],[196,180],[57,-104],[232,133],[-33,226],[-250,422],[128,-6],[54,176],[149,83],[-63,231],[312,338],[333,79],[44,715],[225,550],[204,207],[-10,204]],[[86883,89518],[-408,142],[-1311,114],[-473,-9],[-605,-77],[-479,-11]],[[87110,83929],[-194,792],[-486,-68],[-216,25],[-194,-101]],[[90315,81148],[155,298],[-360,233],[-323,-63],[-252,27],[-230,127],[-195,-107],[13,528],[-528,42],[-400,-27],[-291,233],[-306,-69],[-226,-396],[-249,27],[-60,219],[27,302],[212,405],[-215,155],[23,847]],[[86949,77212],[344,173],[323,-18],[46,154],[219,-72],[-132,181],[233,26],[195,-139],[158,63],[297,-157],[114,243],[321,47],[231,268],[111,259],[-53,200],[147,22],[-1,826],[110,636],[8,394],[99,284],[181,295],[211,202],[204,49]],[[90918,86716],[-275,-344],[-281,78],[-163,-313],[-178,249],[-69,-269],[-96,-11],[-103,-712],[-183,154],[-25,-190],[-519,105],[-76,-127],[-197,40],[-32,-232],[-229,-240],[-72,361],[-161,-115],[-216,84],[-142,-363],[-359,-525],[-199,-453],[-233,36]],[[90315,81148],[430,-312],[-123,-216],[237,-4],[192,-182],[167,71],[316,543],[-83,189],[-42,466],[84,113],[653,259],[327,32]],[[78869,85714],[99,153],[-171,60],[-107,324],[-135,64],[44,210],[-116,73],[78,312],[306,-20],[163,203],[18,422],[108,294],[213,338],[316,219],[194,297],[-167,-1],[-237,174],[-31,365],[173,239],[-292,102],[-232,-56],[-127,188],[-102,-25],[-251,413],[111,266],[-173,142],[98,272],[-164,104],[-529,-54],[-166,84],[-505,-317],[-526,-25],[-95,130],[-334,42],[-419,-165],[-332,3]],[[83607,89677],[-563,21],[-649,155],[-655,363],[-439,446],[-904,1286],[-370,378],[-339,210],[-714,283],[-584,523],[-190,282],[-238,591],[-39,359],[36,519],[264,1532],[-77,404],[-355,361],[-700,434],[-417,172],[-724,146],[-272,15],[-542,-86],[-437,-157],[-526,-267],[-248,-25],[-253,87],[-165,233],[-181,567]],[[90937,90705],[-365,-411],[-194,-377],[-270,-738],[-218,-292],[-185,-100],[-173,30],[-447,239],[-671,211],[-349,61],[-849,86],[-333,104]],[[94542,88735],[634,268],[278,300],[-370,191],[-900,369]]],"transform":{"scale":[0.005026580075832421,-0.004800048000480005],"translate":[228.6735094984169,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/ai.json b/src/onegov/election_day/static/mapdata/2025/ai.json new file mode 100644 index 0000000000..6a26d45cd2 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/ai.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":3101,"properties":{"id":3101,"name":"Appenzell"},"arcs":[[-1,-2,-3,-4]]},{"type":"Polygon","id":3102,"properties":{"id":3102,"name":"Gonten"},"arcs":[[-5,2,-6,-7]]},{"type":"MultiPolygon","id":3104,"properties":{"id":3104,"name":"Schlatt-Haslen"},"arcs":[[[3,4,-8]],[[-9]]]},{"type":"MultiPolygon","id":3111,"properties":{"id":3111,"name":"Oberegg"},"arcs":[[[-10]],[[-11]],[[-12]]]},{"type":"Polygon","id":3112,"properties":{"id":3112,"name":"Schwende-Rüte"},"arcs":[[5,1,-13]]}]}},"arcs":[[[55445,53733],[-2406,-135],[-2018,-343],[-810,683],[-1206,981],[-1292,643],[-1967,1179],[-258,306],[-336,100],[-403,431],[-180,86],[-282,6],[-291,344],[-639,-281],[-128,-190],[-780,581],[-698,-381],[-862,1741]],[[23714,33425],[67,-563],[323,57],[553,232],[812,432],[698,271],[1254,427],[413,360],[202,474],[809,464],[638,226],[551,361],[330,94],[1133,182],[35,517],[-157,583],[166,262],[32,444],[146,221],[101,435],[139,365],[7,257],[576,376],[190,-20],[382,351],[116,2],[341,274],[131,22],[183,425],[183,140],[-1,284],[-241,648],[169,345],[57,338],[-138,107],[-9,243],[-132,218],[-228,83],[-135,156],[21,229],[-345,822],[173,307],[391,235],[64,112],[-228,203],[598,271],[13,97],[-180,482],[-214,22],[-101,194],[-618,429],[248,233],[143,-211],[227,-112],[157,95],[256,-12],[106,100],[520,58],[164,-68],[315,95],[184,224],[254,53],[288,582],[220,76],[94,135],[218,-51],[279,203],[359,169],[389,101],[215,198],[144,464],[157,-63],[420,290],[305,33],[386,-221],[83,130],[675,225],[119,-205],[356,70],[171,-73],[197,90],[148,-191],[309,75],[360,-84],[314,79],[340,204],[232,-1],[461,230],[876,332],[359,41],[649,196],[471,32],[1070,1084],[1069,168],[614,74],[1664,432],[464,335],[1153,145],[1133,-330],[2129,857],[997,526]],[[28095,52978],[253,-46],[230,-507],[73,-635],[-13,-279],[-221,-271],[-699,-354],[-35,-149],[82,-524],[371,-258],[61,-211],[-103,-259],[-535,-440],[-97,-586],[-174,-205],[-185,-24],[-254,-258],[-412,-110],[-349,-317],[-373,-187],[-681,-5],[-400,-360],[-116,-32],[-125,195],[-305,-221],[-221,181],[-173,-47],[-295,-219],[-145,81],[-355,-53],[146,-241],[-69,-536],[-190,-216],[-71,-223],[136,-150],[-97,-99],[-34,-516],[-67,-124],[-245,96],[-155,-239],[-159,-35],[-334,-311],[-188,-34],[-110,-272],[-204,-174],[-105,-307],[-198,-99],[15,-284],[-336,-214],[-222,-218],[382,-111],[76,-344],[194,-168],[-33,-195],[112,-165],[164,69],[246,-519],[181,-136],[-173,-331],[219,-283],[273,-61],[157,-301],[-56,-207],[342,-268],[-129,-382],[244,-25],[254,-393],[234,-74],[211,-406],[212,-219],[313,-161],[176,-310],[-74,-93],[153,-1071],[-122,-57],[120,-317],[-138,-529],[-332,-481],[79,-280],[-136,-133],[8,-465],[159,-421],[-14,-420]],[[40889,59484],[-1217,-143],[-91,350],[-510,-90],[-161,256],[-314,37],[-461,-21],[-959,-420],[-425,-586],[-261,-159],[-636,-263],[-95,-170],[-794,-269],[-362,130],[-404,-78],[-171,-194],[-116,-334],[80,-167],[-85,-231],[-159,-138],[-685,-170],[-54,-114],[-408,-195],[-139,-231],[-501,53],[-211,-148],[-80,-364],[-434,-300],[-585,-63],[-536,-327],[-210,-65],[-520,-301],[-152,-329],[-355,-398],[-153,-21],[-354,-299],[-57,-404],[-224,-129],[5,-211]],[[28095,52978],[-768,-194],[-384,-25],[-8,-161],[-270,3],[-1017,-194],[-152,291],[-270,-45],[-306,-139],[-188,-197],[-223,-64],[-271,-209],[-1269,-190],[-581,64],[-185,86],[-389,52],[-634,-28],[-629,172],[-438,-121],[-286,-244],[-772,-421],[-391,-167],[-94,-111],[-277,-88],[36,-227],[-320,-65],[-406,85],[106,-270],[-696,-331],[-121,-97],[-151,135],[-504,-78],[-141,273],[-455,-226],[-28,109],[-667,-47],[-395,-81],[-340,705],[-421,-80],[-61,-77],[-258,81],[-621,-113],[-422,-118],[-190,90],[-506,-34],[-265,134],[-401,-53],[-189,730]],[[4904,22493],[617,22],[54,375],[315,122],[535,700],[-128,56],[483,387],[-271,233],[98,323],[271,258],[58,328],[-31,460],[-144,163],[-95,583],[150,-28],[1188,528],[324,204],[401,91],[495,197],[374,270],[364,132],[31,175],[186,111],[746,239],[336,261],[807,735],[255,69],[836,6],[1065,482],[416,530],[1286,659],[-145,277],[1517,674],[-14,84],[264,35],[695,247],[453,201],[451,120],[267,-129],[996,278],[184,-17],[876,259],[291,-59],[672,59],[245,88],[1036,144]],[[10877,51493],[-632,-151],[-744,-293],[-648,-573],[-482,-336],[-395,-202],[-409,-375],[-1340,-4693],[-619,-419],[-168,118],[-330,-132],[7,-158],[-758,-278],[-82,65],[-259,-116],[29,-91],[-235,-50],[-759,-315],[-416,-284],[-616,-70],[-590,-410],[54,-112],[-1011,-549],[-106,-495],[-325,-637],[-14,-581],[681,-71],[566,150],[137,-36],[69,-200],[-154,-160],[244,-704],[295,-284],[175,-258],[120,-555],[309,-400],[-508,-323],[254,-412],[90,-266],[-320,-148],[31,-156],[401,-920],[275,-476],[277,-305],[-365,-341],[-396,-500],[-305,-717],[148,-693],[416,-993],[195,-406],[-224,-223],[-113,-12],[-65,-499],[-353,-602],[-8,-523],[-518,-789],[61,-310],[-119,-291],[55,-185],[-97,-246],[54,-142],[298,-358],[-81,-68],[60,-594],[304,-247],[35,-428],[432,-371],[190,106],[51,-107],[269,34],[392,-407],[-67,-171],[202,-396],[-77,-188],[77,-438],[270,-316],[404,-366],[248,-25],[43,-175],[517,-352]],[[40889,59484],[-806,1636],[-306,418],[26,384],[-375,220],[-21,281],[-181,221],[-27,276],[305,380],[-161,511],[-221,355],[204,91],[-49,147],[-200,-40],[-92,109],[-332,-108],[-275,-185],[-1681,-956],[-109,-210],[-368,-3],[-100,112],[-175,451],[-228,-50],[-255,210],[-442,-24],[-816,-373],[-126,-132],[-166,127],[-872,-64],[-1094,652],[-110,-116],[-293,325],[121,100],[-225,112],[-353,44],[64,204],[-118,145],[94,267],[-257,-13],[-372,288],[-367,93],[-212,475],[-184,211],[-59,285],[104,156],[320,-15],[98,160],[-250,275],[-421,-35],[-300,153],[-91,183],[217,156],[79,206],[-154,88],[-228,-126],[-196,-324],[-190,-30],[-351,290],[-18,162],[143,116],[-62,151],[-481,168],[-342,-82],[25,355],[-677,143],[-220,-99],[-541,-481],[-183,-528],[-307,-199],[-310,50],[-241,120],[-279,-67],[-260,-331],[-152,36],[-139,408],[80,307],[-94,235],[-254,113],[-514,0],[-471,232],[-311,47],[-165,102],[-557,68],[-183,131],[-80,206],[64,230],[308,286],[74,193],[-175,536],[178,120],[-18,1068],[-198,143],[-368,-204],[-223,388],[-572,-127],[-817,-380],[208,-484],[-138,-292],[-347,-240],[-267,10],[-266,175],[-293,60],[-320,221],[-142,-159],[-587,-64],[-224,117],[-396,-256],[-368,-25],[-245,136],[-664,132],[-568,45],[-278,-87],[-161,-178],[-51,-322],[-189,-213],[-268,59],[-361,314],[-311,-97],[-966,-427],[-172,-27],[321,-456],[495,-90],[322,-239],[248,-401],[418,-375],[330,-231],[194,-211],[391,-121],[130,-134],[-12,-427],[193,-436],[17,-228],[-73,-690],[184,-431],[-37,-98],[-806,-715],[9,-184],[446,-318],[76,-189],[-119,-542],[248,-258],[222,-713],[326,-206],[202,48],[152,-216],[-57,-186],[-305,-512],[51,-307],[229,-393],[223,-200],[124,-294],[81,-390],[586,-513],[72,-222],[140,-87],[59,-229],[193,-261],[-78,-119],[-388,-131],[0,-106],[-367,-75],[-186,26],[-423,-284],[-318,-49],[-115,63],[-259,-146],[25,-113],[-582,-463],[-1084,-229],[-208,36],[-584,-110],[-15,-124],[-242,-155],[-945,-133],[-213,-56],[-726,-802],[-349,-90],[12,-147],[-128,-337],[63,-154],[-75,-294],[401,-437],[158,-667],[118,-152],[107,-582],[275,-601],[-868,-112]],[[16487,71303],[-126,-190],[321,-166],[159,187],[-310,227],[-44,-58]],[[79808,77395],[-107,49],[-357,399],[-274,123],[-152,408],[-177,24],[-343,218],[-13,152],[-195,310],[10,147],[-251,116],[-201,306],[-83,330],[-224,251],[-303,660],[-179,133],[-143,414],[-162,144],[-73,345],[-203,31],[-649,343],[-182,190],[-129,302],[349,161],[229,205],[451,192],[238,-24],[806,367],[695,-151],[131,157],[143,-27],[32,-255],[297,-19],[-94,-139],[187,-156],[-176,-276],[279,-160],[602,42],[526,222],[112,-265],[361,263],[-153,144],[245,274],[329,-283],[261,157],[561,-174],[154,93],[433,-263],[126,-734],[176,-181],[136,-334],[394,131],[184,238],[378,100],[46,-124],[791,209],[374,193],[278,250],[68,207],[348,-158],[32,114],[-119,409],[143,273],[-152,47],[-32,1367],[-367,112],[-81,382],[210,-3],[104,177],[269,217],[471,249],[93,203],[-79,203],[261,16],[-30,207],[-473,24],[-573,167],[-266,-3],[-390,110],[-507,-30],[-247,-66],[-657,-63],[-602,91],[-381,113],[-70,489],[-104,325],[-96,-128],[-585,-273],[-205,190],[-346,-33],[-247,82],[12,333],[-293,-28],[-349,58],[-309,206],[71,337],[-239,723],[-105,126],[154,246],[-411,316],[-174,23],[174,585],[-233,244],[205,147],[133,440],[-90,213],[-227,-206],[-181,-54],[-259,505],[-527,-155],[-192,-1],[-667,286],[38,214],[-514,214],[-98,305],[100,226],[-324,13],[-176,216],[0,162],[-588,34],[-943,467],[-321,-114],[-380,49],[-79,-238],[99,-350],[79,64],[2,-348],[-138,-335],[96,-268],[-201,-243],[240,-61],[-21,-315],[-196,90],[-419,-316],[122,-481],[-311,-136],[-17,-120],[-215,-7],[-68,-164],[-434,-96],[-53,-188],[-143,-73],[-384,83],[-91,-51],[96,-223],[-472,81],[-32,161],[-360,-129],[-58,148],[-361,-220],[25,-220],[-454,-69],[-234,-96],[34,-116],[-623,-657],[-325,19],[-78,-83],[106,-198],[137,102],[177,-194],[-84,-108],[117,-235],[210,-201],[-69,-365],[-253,-230],[428,-376],[29,30],[347,-518],[-105,-81],[229,-148],[-17,-495],[-254,72],[-423,-27],[-128,-214],[-230,-200],[-270,-93],[403,-403],[319,43],[85,-476],[175,-3],[150,-181],[348,220],[191,-568],[106,-126],[-231,-86],[227,-79],[214,215],[18,169],[460,162],[333,-209],[143,92],[382,-241],[-53,-163],[-695,-601],[-322,-63],[-491,-290],[-322,-267],[-288,-166],[-588,-226],[-393,-272],[-247,258],[-202,-274],[-934,-416],[-473,59],[-284,-53],[-452,-335],[-876,-863],[-562,-354],[258,-138],[-88,-401],[339,-564],[-131,-72],[38,-250],[-117,-150],[169,-66],[-273,-183],[391,-488],[-255,-270],[-640,-339],[-408,-297],[154,-364],[282,-59],[533,188],[325,48],[378,-18],[-1,162],[210,31],[813,229],[581,50],[193,-99],[-64,197],[88,198],[218,-37],[264,174],[91,-298],[71,172],[529,118],[981,166],[507,155],[797,82],[1251,519],[499,163],[555,230],[449,-78],[1294,202],[120,52],[91,277],[192,-136],[-15,-432],[73,-99],[296,46],[329,-43],[61,-158],[-270,-761],[-39,-414],[-361,-458],[51,-28],[571,164],[112,-448],[526,51],[239,-468],[-24,-91],[357,100],[203,-128],[465,251],[379,-32],[-66,132],[293,248],[223,-130],[175,264],[-254,65],[69,249],[146,-30],[31,207],[352,-37],[147,256],[-35,176]],[[99797,97226],[-753,-216],[-447,-12],[-429,-100],[-658,-206],[-527,-32],[-642,-98],[-100,121],[-232,43],[-500,-47],[-757,-178],[-191,-198],[-510,-282],[-550,-196],[-875,-359],[-362,-9],[-565,-152],[-123,352],[149,133],[-2,261],[-746,-195],[-722,-325],[-716,46],[-562,-37],[-530,-80],[-511,4],[3,-87],[-392,26],[-329,-55],[-8,-360],[-311,61],[-297,260],[-651,-44],[29,-180],[-659,8],[-515,166],[-458,-4],[-52,196],[-183,-36],[6,126],[218,454],[-253,202],[-91,243],[-301,272],[98,203],[-126,291],[-426,-5],[-234,-74],[-100,115],[-596,-260],[-2,-173],[149,-312],[-190,-165],[-290,104],[-274,-129],[-254,-211],[-42,-284],[44,-323],[-561,-396],[-421,-163],[2,-402],[-206,-91],[264,-409],[-114,-93],[404,-418],[346,252],[203,-167],[-126,-372],[533,-344],[-55,-197],[437,-33],[73,264],[267,54],[45,-316],[535,87],[369,-89],[38,-413],[311,54],[195,-181],[110,41],[-96,444],[185,173],[210,-197],[194,-636],[222,42],[83,-342],[121,-62],[280,58],[21,-118],[272,55],[177,-334],[116,118],[121,-99],[-353,-187],[-348,6],[153,-573],[-362,-175],[-121,79],[-858,-176],[-140,-112],[37,-326],[-348,-17],[10,-191],[-261,7],[372,-563],[218,-36],[441,131],[342,-149],[294,-55],[257,52],[102,147],[908,145],[288,-289],[246,66],[305,-71],[554,-303],[99,-188],[152,143],[525,-13],[134,111],[157,-395],[-265,-33],[38,-346],[-308,-74],[-8,-114],[448,39],[-89,-850],[-501,-37],[100,-544],[270,-110],[723,40],[263,-82],[-23,-692],[161,-103],[-181,-131],[-464,-559],[-504,-56],[-138,-75],[59,-256],[-553,-141],[48,-74],[476,-5],[396,-313],[843,472],[547,150],[326,-23],[256,125],[237,289],[184,54],[77,-182],[252,-65],[524,185],[161,-42],[1020,134],[651,279],[532,438],[34,162],[526,143],[91,140],[692,-38],[129,181],[-1171,880],[-520,215],[-300,74],[-499,24],[-509,104],[245,256],[-79,68],[255,147],[-253,136],[-371,62],[-540,29],[114,298],[-1018,568],[-130,-99],[-226,287],[-52,-131],[-315,332],[322,436],[-153,335],[-286,321],[148,373],[-138,88],[24,175],[-135,48],[415,108],[680,428],[346,159],[732,436],[1123,726],[320,51],[525,165],[600,450],[275,73],[806,408],[365,78],[-116,181],[245,233],[222,375],[1118,369],[334,68],[-43,86],[192,162],[102,-82],[159,276],[218,39],[-92,239],[474,167],[108,297],[273,79],[37,-108],[331,6],[-202,518]],[[98008,99945],[-169,-99],[291,-94],[37,247],[-159,-54]],[[4904,22493],[123,-71],[3156,-5987],[123,-985],[115,-523],[33,-378],[-89,-303],[278,-652],[3,-299],[128,-328],[122,-114],[109,-446],[269,-383],[181,-432],[1752,-3460],[292,-636],[-40,-172],[146,-202],[284,-221],[-55,-157],[65,-308],[146,-305],[247,-149],[482,-436],[601,-207],[496,-474],[715,-285],[195,34],[920,-61],[277,103],[441,-48],[98,45],[483,-10],[418,-103],[431,-44],[101,-101],[360,-4],[153,-103],[282,61],[336,-126],[246,-365],[57,-235],[221,-75],[325,-226],[126,-240],[303,32],[354,-131],[506,-432],[207,-24],[410,-362],[253,-162],[374,-619],[222,-140],[949,-277],[1201,-967],[705,290],[270,20],[1189,465],[332,277],[799,284],[469,76],[872,272],[882,28],[1001,113],[636,348],[91,176],[284,277],[28,179],[397,681],[328,341],[627,848],[304,332],[636,444],[607,300],[195,373],[619,141],[723,399],[1924,-113],[492,-65],[93,219],[204,-17],[343,398],[195,57],[323,357],[333,117],[47,91],[375,131],[274,222],[439,207],[776,114],[363,-110],[137,455],[450,583],[261,105],[502,86],[272,308],[228,101],[468,344],[43,146],[258,300],[404,22],[101,219],[-24,176],[840,852],[62,256],[267,506],[193,44],[343,204],[173,19],[456,375],[734,483],[342,431],[523,114],[562,355],[223,330],[737,470],[206,401],[220,126],[221,357],[49,259],[159,137],[198,-1],[174,215],[362,183],[850,793],[326,114],[-20,210],[309,300],[-61,103],[237,498],[267,241],[240,352],[-36,369],[167,253],[6,265],[270,323],[223,130],[169,241],[25,199],[320,223],[49,296],[210,495],[79,378],[513,470],[309,99],[532,518],[459,1140],[165,506],[231,500],[2,390],[-365,264],[30,473],[453,1216],[316,669],[-39,769],[90,646],[111,404],[176,436],[-127,344],[158,249],[-220,244],[-392,223],[180,97],[308,306],[4,101],[258,457],[339,188],[250,258],[192,-13],[342,139],[506,500],[-224,811],[-644,1082],[-298,259],[24,215],[-178,824],[279,769],[221,151],[157,237],[757,522],[-239,343],[131,374],[477,133],[83,231],[-9,1178],[206,81],[394,2339],[-256,134],[78,427],[284,167],[81,130],[-296,568],[614,157],[-109,149],[50,359],[-179,209],[265,113],[-103,273],[91,90],[-205,279],[71,232],[303,191],[-75,305],[-20,4931],[-69,1164],[-5219,1188],[-2563,-1491]]],"transform":{"scale":[0.00464041774540926,-0.004800048000480005],"translate":[247.9814329384097,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/ar.json b/src/onegov/election_day/static/mapdata/2025/ar.json new file mode 100644 index 0000000000..45761d0590 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/ar.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":3001,"properties":{"id":3001,"name":"Herisau"},"arcs":[[-1,-2,-3,-4,-5]]},{"type":"Polygon","id":3002,"properties":{"id":3002,"name":"Hundwil"},"arcs":[[-6,-7,4,-8,-9]]},{"type":"Polygon","id":3003,"properties":{"id":3003,"name":"Schönengrund"},"arcs":[[-10,-11,-12]]},{"type":"Polygon","id":3004,"properties":{"id":3004,"name":"Schwellbrunn"},"arcs":[[-13,9,-14,1,-15]]},{"type":"Polygon","id":3005,"properties":{"id":3005,"name":"Stein (AR)"},"arcs":[[-16,-17,7,3,-18]]},{"type":"Polygon","id":3006,"properties":{"id":3006,"name":"Urnäsch"},"arcs":[[-19,10,12,-20,5]]},{"type":"Polygon","id":3007,"properties":{"id":3007,"name":"Waldstatt"},"arcs":[[14,0,6,19]]},{"type":"Polygon","id":3021,"properties":{"id":3021,"name":"Bühler"},"arcs":[[-21,-22,-23,-24,-25]]},{"type":"Polygon","id":3022,"properties":{"id":3022,"name":"Gais"},"arcs":[[21,-26,-27]]},{"type":"Polygon","id":3023,"properties":{"id":3023,"name":"Speicher"},"arcs":[[24,-28,-29,-30,-31]]},{"type":"Polygon","id":3024,"properties":{"id":3024,"name":"Teufen (AR)"},"arcs":[[-32,27,23,-33,15],[-34]]},{"type":"Polygon","id":3025,"properties":{"id":3025,"name":"Trogen"},"arcs":[[30,-35,-36,-37,25,20]]},{"type":"Polygon","id":3031,"properties":{"id":3031,"name":"Grub (AR)"},"arcs":[[-38,-39,-40]]},{"type":"Polygon","id":3032,"properties":{"id":3032,"name":"Heiden"},"arcs":[[-41,-42,-43,-44,38,-45,-46,-47,-48,-49]]},{"type":"MultiPolygon","id":3033,"properties":{"id":3033,"name":"Lutzenberg"},"arcs":[[[-50,-51,-52]],[[-53,45]]]},{"type":"Polygon","id":3034,"properties":{"id":3034,"name":"Rehetobel"},"arcs":[[-54,34,29,-55,39,43]]},{"type":"Polygon","id":3035,"properties":{"id":3035,"name":"Reute (AR)"},"arcs":[[40,-56]]},{"type":"Polygon","id":3036,"properties":{"id":3036,"name":"Wald (AR)"},"arcs":[[35,53,42,-57]]},{"type":"Polygon","id":3037,"properties":{"id":3037,"name":"Walzenhausen"},"arcs":[[-58,49,-59],[-60]]},{"type":"Polygon","id":3038,"properties":{"id":3038,"name":"Wolfhalden"},"arcs":[[-61,47,-62,50,57]]}]}},"arcs":[[[16251,49360],[400,481],[159,-42],[-71,501],[206,174],[504,245],[672,472],[266,52],[472,209],[46,-96],[-151,-242],[121,-348],[207,164],[303,373],[146,250],[731,634],[89,234],[-456,181],[156,367],[49,234],[245,18],[134,142],[403,240],[-77,-521],[89,-70],[388,-81],[451,3],[512,703],[145,-151],[71,150],[254,199],[-274,379],[145,89],[142,258],[549,-212],[115,-203],[105,78],[-2,325],[243,5],[69,355],[-346,196],[-55,158],[660,180],[86,-234],[407,141],[143,-51],[196,103],[247,-419],[-58,-328],[229,-223],[65,323],[-93,348],[121,185],[225,-339],[77,-486],[216,-49],[142,-545],[368,-152],[246,46],[230,-94]],[[6768,55178],[276,-24],[199,-365],[296,11],[207,-77],[98,47],[145,483],[64,-60],[353,-33],[313,-214],[77,-245],[258,-26],[221,-122],[182,254],[487,-275],[168,-23],[211,74],[307,433],[58,282],[234,226],[322,46],[176,-354],[-24,-187],[-177,-174],[-256,23],[20,-188],[-189,-225],[-104,-369],[96,-125],[213,69],[246,-162],[-71,-126],[2,-443],[79,-336],[266,325],[141,-85],[294,176],[58,-78],[251,18],[56,92],[427,41],[121,-449],[128,-117],[-80,-148],[-234,-173],[111,-31],[-173,-216],[51,-246],[210,-247],[346,-88],[205,87],[281,289],[169,-10],[186,96],[-32,272],[781,399],[49,-294],[-86,-66],[187,-639],[-200,-84],[266,-385],[242,-184],[-17,-224],[-114,-87],[50,-201],[-268,-307],[-91,-183],[34,-124],[223,8],[246,-183],[81,-154],[306,286],[124,53],[236,-678],[165,-74]],[[30443,67940],[-144,104],[-394,-494],[-329,-189],[-164,-202],[-112,-239],[-435,-131],[-48,-280],[-109,198],[-212,28],[-436,-98],[-323,-199],[-430,-165],[-231,-29],[-45,-139],[-386,21],[-413,-231],[-31,-106],[-305,-16],[-537,-291],[-161,123],[-59,-158],[-308,56],[-519,374],[-489,95],[-348,-99],[47,203],[-169,-153],[-9,276],[-117,104],[-920,212],[-123,125],[-49,-129],[-396,122],[-355,-67],[-395,149],[-158,165],[-285,-150],[-361,60],[-238,-136],[-116,454],[-2,157],[-183,89],[-300,-85],[-278,201],[-113,-28],[-96,207],[-386,61],[-273,125],[-309,-485],[-254,-296],[-258,24],[-284,191],[-16,200],[-270,383],[-245,28],[-88,-130],[-534,-267],[-100,-358],[-167,156],[-289,-222],[-140,-264],[-308,-77],[-271,810],[-152,138],[-183,-244],[-198,-29],[-140,165],[-188,-112],[-177,109],[-48,-135],[-230,-28],[-319,-328],[-125,-221],[-438,-285],[-459,331],[-314,-215],[-148,-183],[-262,-60],[-96,-216],[-457,-335],[-335,-327],[-335,-126],[-189,299],[-140,119],[-131,-33],[-29,-302],[-184,-197],[-95,140],[95,160],[-136,194],[-25,422],[-182,-287],[-288,-172],[51,-162],[369,-280],[18,-583],[-110,-235],[152,-330],[70,-298],[-58,-328],[33,-416],[137,-300],[-174,-366],[35,-500],[-208,-326],[-92,162],[-96,-40],[46,-266],[-85,-117],[-184,59],[-154,-141],[-307,274],[-269,4],[-194,-278],[-137,-90],[-208,-6],[-318,288],[-204,-427],[-280,-382],[-386,-312],[-36,-300],[71,-286],[-46,-331],[181,-157],[-15,-136],[219,6],[-120,-274],[-137,155],[42,-205],[123,-161],[-20,-134],[396,-804],[96,-329],[-49,-173],[-448,-510],[8,-344],[171,-114],[-49,-220],[138,-308],[37,-571]],[[29962,56178],[256,96],[170,355],[15,179],[-235,468],[34,195],[226,234],[55,281],[-169,811],[278,125],[232,212],[48,198],[-33,329],[-152,170],[-233,1063],[13,267],[114,217],[-55,294],[34,439],[247,162],[52,137],[-188,387],[249,369],[207,618],[-299,535],[-11,257],[-202,257],[35,460],[-139,322],[50,81],[39,425],[239,413],[-202,337],[56,165],[18,712],[-66,183],[-202,9]],[[26913,53669],[112,470],[164,39],[389,-69],[651,349],[266,235],[132,220],[330,189],[112,289],[354,392],[92,188],[-151,257],[266,88],[332,-138]],[[24210,44448],[-39,-241],[159,-204],[-15,-211],[-260,-239],[-53,-245],[-1,-328],[-82,-689],[23,-578],[-69,-96],[-42,-477],[-134,-160],[-101,-407],[136,-245],[67,-372],[-100,-224],[-37,-330],[85,-334],[-285,-164],[-7,-363],[61,-43],[-304,-308],[-86,-258],[36,-438],[220,-519],[147,-48],[174,62],[71,-135],[198,-134],[153,-653],[-39,-261],[221,-435],[-81,-240],[-211,-246],[315,-785],[0,-394],[51,-633],[-129,-87],[375,-267],[97,-186],[606,-181],[190,95],[244,-39],[159,100],[85,-166],[169,1],[192,311],[125,-49],[128,-266],[109,-654],[-14,-298],[84,-252],[-112,-377],[274,-852],[-18,-93],[184,-424],[24,-168],[179,-312],[34,-355],[108,-197],[-127,-78],[150,-393],[110,-481],[67,-134],[100,-488],[-523,-1643],[-567,-1111],[108,-432],[221,-355],[20,-174],[-107,-244],[57,-1094],[-38,-813],[27,-269],[3,-1042],[-178,-129],[-132,-434],[-166,-215],[-21,-323],[84,-338],[205,-199],[162,-309],[198,-179],[968,-57],[266,-333],[151,-69],[231,-386],[429,-349],[214,-271],[140,-261],[-29,-211],[-161,-516],[-428,-614],[-200,-381],[-347,-431],[-150,-365],[-127,37],[-310,-298],[-450,-589],[-390,-267],[-149,-266],[-189,-704],[11,-160],[-98,-331],[160,-24],[330,166],[180,-142],[262,268],[187,-128],[138,291],[219,-69],[195,92],[136,-161],[264,32],[101,-170],[240,175],[95,-169],[-89,-165],[-46,-475],[-133,-599],[-190,-238],[-157,-289],[-173,-680],[-84,-118],[-130,-523],[6,-261],[156,-385],[-118,-141],[-223,-908],[-236,-578]],[[26913,53669],[-421,-350],[-199,-485],[87,-274],[302,-300],[173,-355],[-6,-260],[-220,-209],[-250,41],[-46,-90],[84,-280],[-28,-111],[-256,-124],[-478,-116],[-328,-328],[-383,-716],[-78,-26],[-302,156],[-162,-112],[-60,-379],[187,-492],[-203,-662],[56,-313],[96,-227],[-52,-266],[-9,-655],[34,-141],[172,-78],[26,-200],[-169,-499],[-192,-373],[-78,-997]],[[36715,47858],[-71,21],[-386,751],[-159,5],[-92,195],[-361,98],[-66,106],[-294,36],[-258,268],[-296,64],[-77,-222],[-161,70],[-254,-227],[-12,516],[47,423],[-53,22],[-422,522],[36,90],[-152,109],[9,437],[-60,219],[-97,-57],[-223,834],[-218,-29],[-91,214],[-20,382],[-253,-6],[-269,-137],[-452,157],[-500,819],[-41,165],[-219,257],[-375,183],[-437,90],[-163,-113],[-190,189],[129,279],[-12,613],[-99,218],[-245,335],[104,424]],[[27599,5459],[194,-308],[49,-396],[-61,-123],[-165,-796],[-11,-285],[605,-877],[627,-293],[294,-180],[411,-767],[403,-843],[196,-250],[1192,-341],[204,269],[240,18],[155,81],[148,343],[360,126],[71,-37],[642,290],[122,117],[1932,-206],[321,116],[22,72],[232,4],[-299,401],[28,163],[-204,602],[-1220,3276],[-126,409],[-188,363],[-76,422],[-85,108],[-90,311],[-1,283],[-194,617],[62,287],[-79,646],[-110,1140],[-2199,5669],[-446,401],[-30,165],[-173,25],[-281,346],[-189,299],[-53,415],[54,177],[-141,376],[47,162],[-274,385],[-187,-33],[-36,103],[-216,-45],[-257,467],[16,233],[-212,234],[-42,563],[57,64],[-246,474],[68,232],[-39,176],[84,275],[-43,294],[361,747],[6,495],[245,570],[46,473],[234,223],[-425,1324],[-103,656],[212,679],[276,473],[254,323],[-192,289],[-253,605],[-240,865],[223,140],[-63,252],[-177,390],[354,306],[-215,378],[-84,526],[-122,244],[-206,269],[-169,667],[107,151],[-48,190],[-96,34],[-394,-142],[-475,67],[10,550],[226,603],[75,469],[704,520],[-37,106],[411,388],[429,66],[290,269],[528,299],[325,243],[56,-62],[529,264],[-5,149],[230,125],[117,-112],[431,397],[934,4444],[285,356],[275,191],[336,318],[452,542],[518,278],[300,110],[745,139],[-157,433],[-109,687],[-92,172],[-101,603],[-278,414],[51,279],[-43,146],[81,457],[243,86],[506,759],[807,179],[125,119]],[[14644,36045],[-324,-197],[-128,213],[-248,-155],[-457,-430],[-166,559],[-236,-181],[-444,-448],[-97,135],[-466,358],[-230,71],[37,156],[-125,77],[-74,294],[-114,158],[-160,-56],[-150,133],[-231,-39],[-195,307],[4,175],[-209,162],[-413,30],[-310,-384]],[[6524,26263],[283,105],[435,333],[292,120],[529,433],[245,166],[564,126],[192,-224],[319,275],[424,424],[290,221],[240,91],[86,-366],[318,115],[247,393],[263,539],[362,494],[481,312],[733,660],[226,113],[297,395],[481,316],[130,225],[94,299],[-315,519],[301,150],[258,309],[319,1589],[249,170],[-188,328],[-114,75],[-67,268],[239,144],[-19,417],[-74,248]],[[9908,36983],[-39,-313],[-91,-169],[-613,-590],[-308,-174],[-191,53],[-78,-101],[-85,-336],[-98,-4],[-59,173],[-49,-204],[-391,-410],[38,-164],[-257,51],[-156,-508],[-227,-3],[-131,-110],[-152,184],[-187,-296],[-167,41],[-215,-261],[27,-158],[-236,-171],[-219,208],[-269,-359],[-10,-536],[-226,48],[-171,-197],[-188,8],[-212,-328],[-45,120],[-182,-211],[83,-177],[-140,-84],[-43,-149],[101,-111],[423,-186],[202,-151],[66,-374],[-58,-161],[96,-416],[106,-92],[38,-383],[-16,-296],[76,-327],[95,-153],[29,-263],[-95,-376],[170,-465],[16,-317],[108,-88],[56,-240],[121,-104],[243,-631],[126,-459]],[[14644,36045],[-120,242],[159,139],[-192,287],[121,594],[655,518],[91,208],[232,133],[2,109],[277,153],[-18,108],[262,162],[530,217],[358,86],[60,162],[347,298],[88,351],[-53,102],[129,184],[-98,78],[253,483],[106,316],[-115,7],[-153,438],[-89,102],[59,201],[443,343],[102,-55]],[[6768,55178],[-120,-188],[-411,55],[-30,-416],[-120,-544],[-120,-224],[-141,-117],[-60,-185],[-275,-2],[-142,-314],[-324,-339],[-45,-169],[87,-366],[125,-220],[-64,-114],[-122,-511],[-277,-335],[-210,-128],[-154,-473],[-1804,-552],[-453,-43],[-260,-193],[-374,146],[-190,163],[-552,72],[-147,67],[-316,30],[-166,-115],[94,-202],[160,-133],[20,-527],[91,-210],[314,-424],[104,-446],[190,-1119],[93,-169],[55,-297],[-118,-393],[214,78],[168,216],[275,109],[200,-29],[414,387],[123,352],[108,88],[279,-53],[171,173],[102,576],[81,-64],[389,-579],[170,-4],[-25,-188],[-259,-309],[-208,-170],[-198,-24],[-150,-419],[-232,-772],[-149,-623],[-328,-395],[-11,-266],[-313,-358],[-86,-223],[56,-305],[107,-139],[232,-64],[75,-322],[162,13],[270,-254],[75,-288],[91,-116],[27,-242],[95,-174],[9,-220],[160,-192],[282,-58],[92,-341],[-55,-355],[122,-384],[-21,-162],[93,-213],[263,294],[87,-53],[270,426],[234,63],[127,185],[331,-231],[228,-9],[207,147],[111,303],[191,122],[499,159],[110,-6],[417,135],[79,253],[281,187],[153,36],[183,-235],[347,-100],[131,-195],[75,-429],[261,-670],[228,-459],[335,-387],[119,-404],[259,-169],[135,-391],[127,-205],[9,-150],[124,-62],[102,-433],[71,-97],[6,-331],[95,-241]],[[18080,42011],[19,292],[-80,223],[-16,345],[60,96],[7,305],[-223,135],[-280,458],[31,232],[99,96],[-293,631],[-241,1143],[78,163],[384,380],[-308,472],[-239,225],[147,676],[-295,310],[74,226],[-156,151],[67,561],[-321,149],[-132,-101],[-211,181]],[[36277,60460],[-232,163],[-220,363],[8,158],[-142,375],[-33,351],[16,332],[91,235],[-41,315],[-199,299],[0,175],[-194,390],[28,334],[-119,104],[-86,642],[-213,256],[-106,286],[-17,434],[-158,217],[-74,258],[31,291],[-114,301],[-64,336],[-131,148],[-371,214],[-206,249]],[[36715,47858],[54,146],[406,104],[146,-34],[755,217],[405,437],[-17,107],[197,146],[64,-67],[221,47],[295,269],[385,46],[0,100],[270,125],[55,113],[-134,247],[-42,216],[-148,293],[-408,486],[-56,369],[-87,278],[-155,190],[-159,372],[-36,291],[212,484],[40,176],[-106,205],[-140,-45],[-228,194],[-118,584],[-210,336],[84,513],[-53,179],[-311,301],[-6,174],[562,678],[25,92],[-128,409],[39,869],[-135,413],[9,404],[-91,127],[-272,114],[-656,774],[-174,380],[-224,226],[-308,56],[-182,257],[-78,204]],[[33731,67686],[-281,253],[-150,-20],[-262,-373],[-135,-94],[-158,18],[-151,262],[-174,54],[-300,-200],[-105,235],[19,188],[-450,148],[-235,208],[-450,-58],[-441,-276],[-15,-91]],[[6524,26263],[41,-569],[-62,-237],[-55,-722],[-111,-92],[23,-249],[-191,-663],[187,-216],[0,-230],[126,-438],[-9,-306],[160,5],[140,-315],[272,-136],[210,-732],[91,13],[229,-227],[-50,-195],[176,-311],[61,-209],[196,-255],[130,-256],[-26,-282],[83,-36],[-233,-492],[-113,34],[-206,-99],[-56,-242],[146,-410],[39,-306],[-269,-539],[-289,-379],[-159,-84],[-152,-452],[-200,-346],[-99,-441],[-104,-131],[-167,-22],[-583,-376],[51,-274],[-163,-59],[-193,-241],[-77,80],[-176,-148],[-156,-359],[-437,-464],[-158,-437],[-155,-243],[-38,-448],[26,-158],[-96,-386],[333,-211],[114,-144],[103,44],[291,-453],[429,-222],[240,-331],[214,-95],[81,-242],[209,-33],[343,-353],[20,-212],[210,-207],[176,169],[243,-243],[438,-368],[239,-269],[252,-52],[150,-179],[329,-68],[50,-127],[310,-269],[194,101],[527,-229],[334,-388],[326,-235],[196,-78],[211,42],[333,-134],[143,14],[265,-145],[252,-64],[168,76],[434,-48],[252,82],[641,306],[208,182],[283,97],[114,-129],[388,-106],[399,78],[44,-185],[283,-75],[281,-254],[207,128],[177,-252],[181,-354],[204,-46],[252,295],[357,155],[58,287],[396,253],[173,16],[70,104],[83,603],[299,287],[194,74],[335,331],[490,183],[156,-122],[312,-34],[99,136],[157,-48],[248,591],[239,-275],[210,-351],[725,-578],[116,-227],[-909,-440],[251,-176],[729,-126],[492,78],[591,249],[88,-112],[250,-659],[178,-323],[145,-137],[-40,-92],[322,-104],[149,-478],[240,-413],[449,-69],[338,121],[435,-625],[202,-194],[311,-472],[304,225],[441,208],[62,95],[664,485],[227,90],[215,-110],[136,70],[413,-14]],[[24210,44448],[-165,34],[-129,-112],[-280,-59],[-84,-107],[-175,8],[-164,-334],[-239,-374],[-264,6],[-19,-140],[-162,-184],[-409,-323],[-175,-241],[-276,-32],[-364,29],[-253,-100],[-452,-278],[36,-197],[-199,-195],[-40,-322],[-169,366],[-540,-90],[-220,25],[-85,-89],[-168,84],[-358,-62],[-109,-150],[-112,113],[-131,-46],[-59,165],[-366,168]],[[60068,62458],[15,387],[-71,226],[13,374],[-260,773],[23,306],[66,156],[-275,-136],[-244,300],[37,858]],[[54866,55643],[-324,517],[-221,115],[-141,-139],[-144,85],[14,236],[355,374],[-40,139],[128,230],[550,417],[101,149],[215,73],[21,104],[343,330],[131,14],[-118,371],[45,328],[356,368],[163,74],[223,280],[141,-95],[262,91],[307,369],[220,196],[-45,111],[303,269],[107,-98],[359,281],[286,291],[383,200],[246,316],[162,22],[75,158],[171,132],[135,243],[193,70],[240,194]],[[48006,58650],[5,-106],[-212,-237],[64,-173],[209,-145],[293,33],[175,-261],[-69,-151],[-223,15],[-72,-149],[41,-269],[128,-200],[156,-463],[248,-75],[259,-273],[179,12],[-66,-253],[83,-136],[-45,-194],[246,-42],[157,-105],[-85,-95],[205,-308],[76,110],[762,-618],[608,61],[116,-120],[88,125],[568,353],[308,23],[178,-199],[159,47],[122,-427],[69,-105],[257,2],[76,199],[1171,905],[192,175],[231,102],[64,-103],[139,38]],[[55427,65010],[-114,-124],[0,-304],[-80,-224],[-272,-10],[-289,-232],[-308,-6],[-95,-418],[-339,-49],[-201,78],[-268,-155],[-174,-489],[38,-59],[-282,-114],[2,-218],[-282,-81],[-116,61],[-284,-253],[-183,-23],[127,-113],[-97,-172],[-39,-281],[-176,12],[-128,301],[-318,-76],[-257,-255],[-114,138],[-191,-50],[-97,107],[-307,-123],[-214,-235],[-120,-276],[-145,-60],[-168,-245],[18,-294],[-85,-154],[-137,-889],[-190,-269],[-511,4],[-14,129],[-539,-26],[-54,-541],[-186,-236],[-232,-136]],[[59372,65702],[-470,-120],[-938,-328],[-198,-565],[-90,-348],[-185,141],[-35,-209],[-478,250],[-165,246],[-299,-156],[-227,-28],[-224,336],[-150,64],[-139,-52],[-347,77]],[[72298,66026],[-749,125],[-441,-268],[-756,-405],[-590,-234],[-453,-359],[-303,9],[-311,-57],[-251,-170],[-322,-103],[-405,17],[-137,-164],[-90,29],[-281,-311],[-18,-275],[-318,-558],[-237,-305],[-191,-55],[-430,27],[-222,152],[-108,151],[-603,198],[-106,142],[-183,40],[-131,288],[38,116],[-150,256],[22,273],[-96,65],[-29,215],[-450,-189],[-151,69],[-716,-184],[-468,-6],[-96,-218],[-285,-341],[-197,-165],[-353,-103],[-204,-164],[-166,19],[-245,-367],[-117,-38],[-428,-412],[-75,26],[-307,-319],[-121,-15]],[[54866,55643],[43,-101],[-154,-149],[157,-311],[113,-484],[-213,-360],[19,-262],[126,-209],[15,-265],[261,-209],[-18,-364],[213,-396],[1163,-3197],[486,360],[543,-550],[90,180],[445,266],[203,-326],[321,-86],[281,-408],[234,-95],[180,-290],[1371,-1117],[900,-609],[840,-928],[565,-647],[1406,325],[1677,128],[1786,1411],[3636,-1124],[-10,1532],[-125,401],[-76,81],[91,811],[-108,252],[-168,59],[-382,2432],[228,364],[-82,90],[-249,9],[-148,246],[225,220],[111,242],[-222,124],[-136,267],[412,1942],[35,77],[-160,139],[-186,269],[-140,109],[238,232],[148,217],[121,380],[-137,195],[235,374],[163,127],[218,277],[150,114],[285,405],[-118,217],[-229,45],[-201,-45],[8,2618],[21,259],[157,510],[-19,290],[-153,217],[-191,107],[362,155],[-18,96],[83,779],[130,586],[-232,329],[349,382],[-115,355],[267,141],[128,151],[183,1021]],[[53371,71726],[163,-957],[-187,84],[369,-494],[182,209],[144,-322],[-92,-179],[106,-270],[22,-364],[-82,-202],[25,-281],[-86,-108],[100,-130],[354,210],[193,63],[168,-37],[611,61],[117,-318],[-168,-266],[98,-500],[165,-356],[155,-3],[77,-217],[-221,-128],[114,-724],[-104,-365],[-6,-208],[-266,59],[-240,-362],[148,-346],[197,-265]],[[59148,82490],[-295,-134],[-292,222],[-244,585],[-187,46],[-201,273],[-172,-73],[-226,107],[-228,218],[-325,-153],[-232,-216],[-169,96],[-356,71],[-133,248],[-226,91],[-443,-45],[-167,-64],[-51,-263],[99,-16],[-84,-679],[-170,-221],[-270,-568],[-52,-388],[129,-109],[-48,-161],[446,-1110],[-58,-68],[124,-345],[44,-364],[-108,-226],[57,-227],[-64,-115],[13,-617],[115,-482],[-286,-73],[42,-285],[-241,-293],[106,-304],[-691,-253],[-62,-159],[97,-322],[104,28],[51,-345],[127,-338],[-39,-166],[141,0],[18,-441],[219,-104],[-69,-314],[-169,-374],[-297,-428],[-445,523],[128,-246],[-282,-304],[-1,-454],[112,20],[56,-243],[106,131],[201,83],[-51,-135],[43,-212],[-440,-321],[-240,-375],[-80,-259],[-161,-114]],[[61717,76541],[-229,124],[-49,173],[74,112],[-22,196],[-169,223],[-213,105],[-162,-11],[-196,144],[-8,354],[-105,161],[-51,267],[112,125],[-41,349],[-132,141],[95,284],[-17,215],[-221,249],[-168,424],[-143,215],[-30,416],[112,589],[-190,301],[-274,43],[-30,194],[-435,420],[-77,136]],[[59372,65702],[-23,641],[79,606],[-15,290],[70,231],[-92,146],[-72,325],[28,279],[-109,201],[88,482],[261,161],[157,320],[21,151],[281,605],[-204,615],[90,500],[-6,270],[-64,109],[186,315],[-17,302],[383,290],[131,25],[237,224],[124,266],[-330,1102],[-35,490],[66,308],[143,392],[1,172],[110,110],[246,-70],[200,204],[255,542],[158,130],[-3,105]],[[53371,71726],[-261,-204],[-555,-332],[-207,-80],[-351,-15],[-699,-413],[-577,-77],[-138,240],[-161,-27],[32,-375],[-402,-235],[-105,-430],[-328,22],[7,-291],[-240,-127],[-278,-71],[-241,65],[-185,-75],[-244,-401],[-435,-190],[-337,37],[-185,-98],[-228,291],[-224,-14],[33,-331],[-118,-44],[-187,142],[-371,130],[-529,-115],[-181,104],[-88,169],[-185,153],[-114,371],[13,191],[-185,560],[-50,-60],[-406,388],[-357,154],[-164,-45],[-503,286],[-382,-51],[-397,245],[-151,-71],[-193,288],[-256,80],[-282,-122],[-194,176],[-555,-266],[-104,183],[-136,73],[-328,-193],[-252,-231],[-153,-283],[-148,-156],[-89,-243],[-301,-311],[-324,21],[-113,-131],[-100,83],[-196,-159],[-367,-170],[-304,-225],[-54,-318],[-253,-288],[-267,97],[-224,6],[-62,131],[-180,99],[-118,237],[-428,-272],[-191,-191],[-861,-513],[-158,-13],[-188,-194],[-305,-156],[-653,-251],[-529,-28],[-110,-176]],[[36277,60460],[119,25],[858,504],[284,-305],[187,-55],[131,201],[36,306],[112,168],[270,100],[782,-185],[171,-129],[257,24],[275,242],[156,-111],[410,61],[98,150],[223,-209],[204,-56],[185,-167],[187,-9],[242,227],[96,277],[-145,458],[569,360],[398,120],[156,-367],[256,193],[139,-136],[12,-1011],[-124,-114],[122,-507],[-51,-183],[-216,-271],[-44,-218],[56,-194],[127,-124],[388,-65],[332,-141],[328,-220],[358,1],[177,-108],[66,-222],[-56,-291],[97,-386],[106,-34],[181,313],[194,63],[385,-161],[213,189],[128,500],[377,455],[153,94],[472,-135],[-18,-336],[239,77],[335,-158],[43,-144],[-100,-109],[13,-154],[244,-274],[133,27],[137,307],[159,120],[107,-83]],[[38986,62176],[31,55],[216,-215],[-111,-178],[-224,158],[88,180]],[[63816,76777],[-58,-3],[-590,-394],[-160,121],[-661,-185],[-159,23],[-50,191],[-421,11]],[[72853,70257],[-92,-11],[-342,234],[-360,-281],[-216,44],[-285,136],[-309,-9],[-301,-128],[-78,248],[-431,-81],[484,607],[-361,26],[-247,-265],[-483,342],[-84,-101],[-90,356],[187,201],[-86,88],[-227,-58],[-94,179],[-118,-47],[-141,385],[-135,-63],[-350,76],[-171,303],[-251,302],[41,286],[-367,492],[-219,-72],[-108,349],[-445,-111],[-159,60],[-18,299],[231,256],[-59,261],[-208,-20],[-341,-178],[-311,-33],[-126,-144],[-28,251],[-128,352],[-234,49],[-1,-290],[-115,-121],[-51,162],[-589,-114],[-115,148],[-254,473],[-101,313],[78,47],[-529,463],[-82,168],[-155,619],[-63,72]],[[72298,66026],[248,731],[-85,108],[-108,344],[285,282],[446,321],[178,255],[-273,462],[190,174],[-117,63],[81,141],[-26,237],[91,69],[-236,534],[61,379],[-180,131]],[[75502,92097],[-77,-79],[-278,-16],[-261,104],[-456,85],[-358,-180],[-113,-383],[-282,-67],[-440,-529],[-400,129],[-166,-15],[-119,156],[-265,-232],[-97,33],[-286,-156],[32,-130],[-133,-36],[-234,-466],[-512,-570],[-31,-220],[-184,-302],[-368,-345],[-551,-395],[3,-104],[-233,-130],[-66,209],[-85,-56],[-441,-492],[-175,-135],[-459,-87],[-333,-178],[-1099,-231],[-184,-111],[-116,-214],[-252,-26],[-176,-209],[35,-89],[-383,-263],[-113,90],[-52,-129],[-195,-145],[-195,114],[-129,-56],[-129,141],[-118,-5],[-335,-282],[-188,-67],[-413,90],[-654,-17],[-174,-63],[-400,-254],[-67,-105]],[[73550,82224],[198,264],[73,6],[198,370],[84,349],[428,487],[-35,557],[-210,1940],[25,259],[283,213],[-163,119],[-224,412],[157,291],[-3,510],[87,146],[-186,184],[39,258],[130,89],[164,-94],[54,112],[151,-144],[75,577],[53,125],[-64,234],[54,313],[220,39],[0,186],[123,9],[-17,216],[478,-111],[47,87],[-109,270],[-184,9],[88,422],[-69,100],[52,199],[-45,870]],[[62797,85679],[81,-46],[55,-407],[-37,-119],[218,-219],[-215,-79],[82,-151],[289,-253],[120,-178],[-23,-233],[172,-7],[-80,-100],[64,-529],[200,-44],[28,149],[368,284],[67,230],[220,93],[-74,63],[78,174],[380,-199],[174,362],[347,67],[30,-127],[260,-111],[72,333],[41,-183],[234,26],[-24,294],[297,-104],[203,312],[461,246],[348,34],[14,-166],[310,49],[707,0],[139,-227],[9,-139],[252,-241],[128,-354],[155,-77],[260,125],[78,154],[114,-5],[270,348],[122,-21],[193,185],[340,118],[197,-28],[101,-227],[237,108],[208,-137],[37,186],[257,422],[460,111],[224,-88],[-454,-601],[-154,-317],[291,-282],[223,-528],[80,-392],[-37,-40],[205,-246],[181,-612],[-136,-379],[201,-225],[146,86],[296,8],[344,186],[113,234],[206,-21]],[[80948,82667],[26,266],[332,229],[217,-24],[74,178],[249,188],[422,1],[387,87],[215,-45],[136,98],[14,-133],[200,228],[310,-134]],[[76270,79549],[163,91],[317,65],[-18,208],[252,208],[40,-139],[251,122],[22,-153],[329,-76],[-3,259],[267,-79],[137,248],[303,90],[46,156],[151,6],[11,114],[217,129],[-85,456],[292,298],[136,-85],[15,298],[-167,59],[140,230],[-67,253],[96,318],[-1,329],[-55,-60],[-69,330],[55,226],[265,-46],[223,107],[657,-442],[410,-32],[0,-153],[123,-205],[225,-12]],[[73790,80839],[420,-278],[37,-140],[-151,-139],[166,-699],[77,-182],[271,60],[368,250],[93,277],[119,-375],[196,-10],[494,295],[173,11],[217,-360]],[[73550,82224],[-53,-106],[165,-458],[93,-397],[-23,-288],[58,-136]],[[75914,95822],[117,-223],[130,-86],[-184,-212],[114,-158],[-68,-230],[177,-601],[244,-387],[410,-442],[182,-92],[-110,-395],[-135,-3],[-490,180],[-313,-197],[-222,-250],[-30,-314],[-234,-315]],[[80305,97889],[-173,99],[-520,-141],[30,-121],[-337,-284],[-407,-10],[-56,-252],[-180,-100],[-135,-201],[-130,-324],[-256,114],[-213,-108],[-236,388],[61,54],[-137,269],[-241,-151],[-605,-652],[-50,112],[-806,-759]],[[81949,97833],[-20,253],[-157,-21],[-660,-281],[-174,-218],[-431,-259],[-206,373],[4,209]],[[83577,84595],[-229,-76],[-117,345],[-403,39],[-166,-175],[0,-199],[-356,-39],[-58,64],[-37,477],[60,350],[297,26],[-85,553],[-296,-77],[-64,230],[27,280],[-207,-26],[-5,256],[-287,133],[-58,115],[-351,-74],[-138,88],[24,191],[-86,47],[-106,-231],[-69,187],[-216,129],[-29,397],[-151,285],[-49,216],[-736,177],[-23,180],[-284,-122],[-492,234],[-139,119],[9,173],[-119,197],[1,208],[256,335],[207,101],[87,151],[-26,186],[288,305],[-8,135],[-261,545],[-46,194],[48,202],[296,162],[-34,157],[39,361],[107,186],[70,530],[-82,310],[117,186],[-56,202],[55,435],[165,168],[-56,256],[336,278],[102,179],[-78,96],[53,196],[-5,422],[152,228],[30,400],[-28,376],[374,238],[153,280],[323,263],[186,335],[297,89],[137,159],[112,-85]],[[83530,83606],[80,88],[-184,388],[143,86],[8,427]],[[89977,93115],[147,479],[10,270],[175,235],[56,449],[-60,75],[-145,525],[85,277]],[[84050,97441],[-160,-170],[10,-378],[-64,-165],[11,-355],[102,-116],[12,-212],[-240,-468],[-102,-333],[-128,-83],[168,-80],[69,234],[165,19],[-42,-138],[69,-419],[101,7],[-106,-196],[59,-99],[262,55],[25,-154],[466,122],[9,208],[485,125],[-6,105],[542,132],[28,-132],[352,99],[116,199],[170,-270],[-96,-32],[266,-163],[234,20],[87,-90],[109,212],[676,56],[17,-163],[294,14],[105,-67],[55,123],[268,-2],[25,-222],[-120,-85],[161,-82],[57,-286],[196,1],[338,322],[103,-339],[364,-22],[-48,-420],[-107,-154],[185,-115],[134,49],[169,-148],[-55,-226],[137,-44]],[[90245,95425],[56,162],[-110,629],[-262,-110],[-61,264],[-283,142],[-192,33],[-533,414],[-49,122],[-339,16],[-169,122],[-19,208],[-203,65],[-283,-115],[-378,11],[-39,161],[-491,-30],[-59,-60],[-386,190],[-66,-115],[-162,148],[-322,89],[-47,-50],[-426,40],[-768,-148],[-290,-145],[-314,-27]],[[80305,97889],[224,166],[130,384],[-148,200],[48,72],[-87,318],[146,99],[-93,219],[-125,-79],[-418,-35],[-41,178],[-214,314],[16,141],[-241,128],[-86,-159],[-225,-19],[-339,-195],[-77,-143],[-189,171],[-213,52],[-773,-254],[-353,-64],[-477,-719],[177,-271],[-120,-89],[-279,-55],[147,-156],[-401,-484],[-171,-531],[-159,-201],[-225,-414],[174,-336],[-93,-78],[94,-227]],[[63816,76777],[258,144],[73,-62],[114,157],[249,112],[286,-72],[305,251],[95,-99],[103,120],[364,217],[-15,93],[199,147],[17,200],[283,422],[254,96],[97,149],[172,-20],[266,120],[144,143],[121,-71],[546,218],[262,60],[97,277],[15,226],[275,124],[38,-214],[258,-172],[467,14],[342,-324],[103,-27],[226,-238],[418,182],[305,-92],[177,125],[64,-74],[374,125],[132,301],[149,101],[466,-138],[174,24],[93,-222],[215,114],[295,237],[206,347],[-186,506],[303,183],[80,315],[127,-35],[-40,-418],[138,14],[15,285],[455,191]],[[62797,85679],[-133,-244],[-256,-265],[-182,-104],[-140,-425],[-226,-218],[-219,-76],[-580,-348],[-212,-58],[-179,-150],[-311,-18],[-189,-268],[-179,-57],[-254,-185],[-332,-73],[-112,-253],[116,-268],[-97,-184],[-164,5]],[[80948,82667],[-69,-214],[68,-289],[358,-203],[-26,-202],[465,-271],[134,1],[366,147],[181,-478],[126,50],[158,196],[63,-202],[-92,-416],[-143,-139],[162,-232],[-121,-553],[121,-23],[286,-299],[-107,-232],[73,-120],[166,-685],[-49,-319],[215,-195],[244,-55],[204,27],[-8,-315],[172,-78],[241,31],[120,-171],[279,120],[218,251],[73,-308],[48,-463],[366,-136],[319,-57],[387,44],[243,78],[354,28],[271,-104],[186,3],[399,-158],[329,-23],[21,-196],[-181,-15],[54,-192],[-64,-192],[-329,-236],[-187,-205],[-72,-168],[-146,3],[55,-362],[256,-106],[23,-1295],[106,-44],[-100,-258],[83,-388],[-22,-108],[-243,150],[-47,-196],[-194,-237],[-260,-183],[-552,-198],[-32,118],[-263,-95],[-128,-226],[-275,-123],[-94,316],[-123,172],[-88,694],[-302,250],[-107,-89],[-391,165],[-182,-149],[-229,268],[-171,-259],[107,-136],[-252,-250],[-78,251],[-366,-210],[-420,-39],[-194,152],[123,260],[-131,148],[66,132],[-207,18],[-23,242],[-100,25],[-91,-149],[-484,143],[-562,-348],[-165,24],[-314,-182],[-160,-195],[-243,-152],[90,-286],[202,-235],[213,-103],[163,-167],[142,-29],[51,-327],[116,-143],[97,-385],[124,-126],[192,-580],[175,-282],[58,-313],[140,-290],[175,-110],[-7,-139],[152,-446],[232,-198],[123,-23],[106,-386],[205,-128],[235,-366],[90,130],[198,-23],[75,-184],[92,180],[253,171],[60,250],[379,297],[257,324],[683,-109],[213,227],[-184,67],[42,152],[250,323],[375,34],[134,155],[50,189],[-79,234],[124,106],[145,-28],[474,332],[-17,98],[241,95],[-33,97],[308,385],[137,-69],[324,144],[24,-107],[226,90],[-84,42],[-129,348],[-258,232],[187,32],[98,221],[155,48],[68,153],[208,166],[276,56],[203,257],[277,188],[395,335],[67,137],[-19,295],[-252,256],[-332,4],[-33,70],[385,134],[-41,242],[97,71],[351,53],[323,529],[126,124],[-112,98],[16,655],[-184,78],[-503,-38],[-188,104],[-70,515],[349,35],[62,805],[-312,-37],[6,108],[214,70],[-26,327],[184,32],[-109,374],[-94,-105],[-366,12],[-105,-135],[-69,178],[-337,250],[-262,104],[-171,-62],[-201,273],[-633,-137],[-71,-139],[-179,-50],[-198,47],[-245,146],[-308,-123],[-151,33],[-260,534],[183,-7],[-7,181],[242,16],[-26,309],[98,106],[598,167],[84,-75],[252,165],[-106,543],[242,-6],[246,177],[-84,94],[-81,-111],[-123,315],[-190,-51],[-14,111],[-280,4],[-58,324],[-154,-39],[-136,602],[-146,186],[-129,-164],[67,-420],[-76,-39],[-137,171],[-216,-51],[-27,392],[-257,84],[-372,-82],[-32,298],[-186,-51],[-51,-250],[-304,32],[38,186],[-371,326],[88,352],[-142,158],[-241,-238],[-282,395]],[[72853,70257],[392,335],[610,817],[315,317],[198,50],[330,-56],[650,395],[141,259],[172,-244],[274,257],[410,214],[425,410],[342,274],[224,61],[485,569],[37,154],[-267,228],[-99,-87],[-232,198],[-321,-153],[-12,-161],[-149,-203],[-159,75],[161,81],[-139,301],[-68,356],[-242,-208],[-105,172],[-122,2],[-59,451],[-222,-41],[-281,382],[188,88],[249,392],[296,25],[176,-67],[12,468],[-159,140],[73,77],[-242,490],[-319,328],[177,218],[48,346],[-147,189],[-81,224],[59,102],[-124,183],[-95,-96],[-20,266],[227,-18],[434,622],[-24,110]],[[89977,93115],[-150,-194],[6,-598],[80,-422],[-168,-421],[42,-162],[-109,-138],[136,-265],[-82,-72],[-25,-343],[-122,-368],[95,-174],[-145,-325],[-434,-217],[-76,374],[-99,-17],[-381,-279],[-242,223],[-163,-167],[14,191],[-225,50],[-179,-143],[-7,121],[-381,-228],[-209,-313],[-242,22],[-218,-538],[-185,54],[-509,30],[-596,86],[-179,211],[-261,15],[-206,-88],[159,-365],[180,-615],[180,-122],[52,-285],[-299,165],[-80,-422],[34,-263],[286,-372]],[[85269,86741],[67,-113],[162,70],[297,5],[88,-275],[-68,-192],[210,-258],[63,-230],[177,-191],[-152,-430],[123,-85],[36,-186],[320,4],[358,-157],[459,-8],[-20,170],[454,42],[207,-246],[217,-58],[5,342],[230,51],[273,-24],[-3,82],[356,-4],[370,76],[391,35],[499,-43],[503,307],[520,185],[2,-248],[-104,-126],[85,-333],[394,145],[252,8],[610,340],[384,186],[355,266],[133,188],[527,168],[348,45],[232,-155],[448,92],[367,31],[757,289],[311,12],[710,276],[1012,235],[157,128],[526,214],[178,169],[239,2],[406,238],[64,630],[-45,202],[228,-14],[11,258],[-124,20],[62,151],[-142,537],[-104,222],[-548,276],[-663,488],[-270,46],[-51,112],[-358,194],[-235,371],[-501,-62],[-629,121],[-278,83],[-334,186],[-310,248],[-645,611],[-41,339],[-337,1],[-116,171],[-196,143],[-149,-50],[-229,140],[-248,313],[-758,759],[-135,70],[-52,233],[-382,179],[-216,291],[56,103],[-162,236],[-10,397],[-270,90],[-467,-136],[-835,-515],[-76,201]],[[95791,89297],[110,51],[-25,-233],[-203,89],[118,93]],[[83577,84595],[132,10],[399,305],[144,167],[-31,307],[30,268],[368,323],[202,-99],[132,156],[-104,296],[2,164],[418,249]],[[84050,97441],[24,177],[-749,509],[-210,108],[-325,-9],[-572,-454],[-269,61]]],"transform":{"scale":[0.006305995653321437,-0.004800048000480005],"translate":[164.70337033175485,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/be.json b/src/onegov/election_day/static/mapdata/2025/be.json new file mode 100644 index 0000000000..dcbe17240a --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/be.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":301,"properties":{"id":301,"name":"Aarberg"},"arcs":[[-1,-2,-3,-4,-5]]},{"type":"Polygon","id":302,"properties":{"id":302,"name":"Bargen (BE)"},"arcs":[[-6,3,-7,-8,-9,-10]]},{"type":"Polygon","id":303,"properties":{"id":303,"name":"Grossaffoltern"},"arcs":[[-11,-12,-13,-14,-15,-16]]},{"type":"Polygon","id":304,"properties":{"id":304,"name":"Kallnach"},"arcs":[[7,-17,-18,-19,-20,-21,-22,-23]]},{"type":"Polygon","id":305,"properties":{"id":305,"name":"Kappelen"},"arcs":[[-24,-25,-26,-27,-28,-29,-30,4,5]]},{"type":"Polygon","id":306,"properties":{"id":306,"name":"Lyss"},"arcs":[[-31,13,-32,0,29,-33,-34,-35]]},{"type":"Polygon","id":307,"properties":{"id":307,"name":"Meikirch"},"arcs":[[-36,-37,-38,-39]]},{"type":"Polygon","id":309,"properties":{"id":309,"name":"Radelfingen"},"arcs":[[-40,16,6,2,-41,-42]]},{"type":"Polygon","id":310,"properties":{"id":310,"name":"Rapperswil (BE)"},"arcs":[[-43,-44,-45,-46,-47,-48,-49,-50,10]]},{"type":"Polygon","id":311,"properties":{"id":311,"name":"Schüpfen"},"arcs":[[-51,36,-52,11,49,-53]]},{"type":"Polygon","id":312,"properties":{"id":312,"name":"Seedorf (BE)"},"arcs":[[-54,40,1,31,12,51,35]]},{"type":"Polygon","id":321,"properties":{"id":321,"name":"Aarwangen"},"arcs":[[-55,-56,-57,-58,-59,-60,-61]]},{"type":"Polygon","id":322,"properties":{"id":322,"name":"Auswil"},"arcs":[[-62,-63,-64,-65]]},{"type":"Polygon","id":323,"properties":{"id":323,"name":"Bannwil"},"arcs":[[-66,57,-67,-68,-69,-70,-71]]},{"type":"Polygon","id":324,"properties":{"id":324,"name":"Bleienbach"},"arcs":[[-72,-73,-74,-75,-76,-77]]},{"type":"Polygon","id":325,"properties":{"id":325,"name":"Busswil bei Melchnau"},"arcs":[[-78,-79,-80,-81]]},{"type":"Polygon","id":326,"properties":{"id":326,"name":"Gondiswil"},"arcs":[[-82,-83,-84,-85,64,-86]]},{"type":"Polygon","id":329,"properties":{"id":329,"name":"Langenthal"},"arcs":[[-87,79,-88,75,-89,54,-90,-91]]},{"type":"Polygon","id":331,"properties":{"id":331,"name":"Lotzwil"},"arcs":[[76,87,78,-92,-93]]},{"type":"Polygon","id":332,"properties":{"id":332,"name":"Madiswil"},"arcs":[[-94,-95,85,63,-96,-97,-98,-99,-100,91,77]]},{"type":"Polygon","id":333,"properties":{"id":333,"name":"Melchnau"},"arcs":[[80,86,-101,82,-102,93]]},{"type":"Polygon","id":335,"properties":{"id":335,"name":"Oeschenbach"},"arcs":[[-103,-104,-105,-106]]},{"type":"Polygon","id":336,"properties":{"id":336,"name":"Reisiswil"},"arcs":[[94,101,81]]},{"type":"Polygon","id":337,"properties":{"id":337,"name":"Roggwil (BE)"},"arcs":[[60,-107,-108,89]]},{"type":"Polygon","id":338,"properties":{"id":338,"name":"Rohrbach"},"arcs":[[-109,95,62,-110]]},{"type":"Polygon","id":339,"properties":{"id":339,"name":"Rohrbachgraben"},"arcs":[[96,108,-111,-112,-113,-114]]},{"type":"Polygon","id":340,"properties":{"id":340,"name":"Rütschelen"},"arcs":[[92,99,-115,71]]},{"type":"Polygon","id":341,"properties":{"id":341,"name":"Schwarzhäusern"},"arcs":[[-116,-117,-118,58,65]]},{"type":"Polygon","id":342,"properties":{"id":342,"name":"Thunstetten"},"arcs":[[-119,55,88,74,-120,-121]]},{"type":"Polygon","id":344,"properties":{"id":344,"name":"Ursenbach"},"arcs":[[104,-122,97,113,-123]]},{"type":"Polygon","id":345,"properties":{"id":345,"name":"Wynau"},"arcs":[[-124,106,59,117]]},{"type":"Polygon","id":351,"properties":{"id":351,"name":"Bern"},"arcs":[[-125,-126,-127,-128,-129,-130,-131,-132,-133,-134,-135]]},{"type":"Polygon","id":352,"properties":{"id":352,"name":"Bolligen"},"arcs":[[-136,-137,-138,-139,-140,-141,-142,-143]]},{"type":"Polygon","id":353,"properties":{"id":353,"name":"Bremgarten bei Bern"},"arcs":[[-144,-145,129]]},{"type":"Polygon","id":354,"properties":{"id":354,"name":"Kirchlindach"},"arcs":[[-146,143,128,-147,37,50,-148]]},{"type":"Polygon","id":355,"properties":{"id":355,"name":"Köniz"},"arcs":[[134,-149,-150,-151,-152,-153,-154,-155]]},{"type":"Polygon","id":356,"properties":{"id":356,"name":"Muri bei Bern"},"arcs":[[-156,-157,-158,-159,-160,148,133,-161,-162]]},{"type":"Polygon","id":357,"properties":{"id":357,"name":"Oberbalm"},"arcs":[[-163,-164,151,-165,-166]]},{"type":"Polygon","id":358,"properties":{"id":358,"name":"Stettlen"},"arcs":[[161,-167,137,-168]]},{"type":"Polygon","id":359,"properties":{"id":359,"name":"Vechigen"},"arcs":[[-169,155,167,136,-170,-171,-172,-173]]},{"type":"Polygon","id":360,"properties":{"id":360,"name":"Wohlen bei Bern"},"arcs":[[-174,-175,41,53,38,146,127]]},{"type":"Polygon","id":361,"properties":{"id":361,"name":"Zollikofen"},"arcs":[[-176,-177,130,144,145]]},{"type":"Polygon","id":362,"properties":{"id":362,"name":"Ittigen"},"arcs":[[-178,131,176,-179,139]]},{"type":"Polygon","id":363,"properties":{"id":363,"name":"Ostermundigen"},"arcs":[[166,160,132,177,138]]},{"type":"Polygon","id":371,"properties":{"id":371,"name":"Biel/Bienne"},"arcs":[[-180,-181,-182,-183,-184,-185,-186,-187,-188,-189,-190]]},{"type":"Polygon","id":372,"properties":{"id":372,"name":"Evilard"},"arcs":[[-191,-192,185,-193]]},{"type":"Polygon","id":381,"properties":{"id":381,"name":"Arch"},"arcs":[[-194,-195,-196,-197]]},{"type":"Polygon","id":382,"properties":{"id":382,"name":"Büetigen"},"arcs":[[34,-198,-199,-200,-201]]},{"type":"Polygon","id":383,"properties":{"id":383,"name":"Büren an der Aare"},"arcs":[[-202,-203,-204,-205,-206,-207,-208,-209,-210,-211]]},{"type":"Polygon","id":385,"properties":{"id":385,"name":"Diessbach bei Büren"},"arcs":[[200,-212,206,-213,-214,14,30]]},{"type":"Polygon","id":386,"properties":{"id":386,"name":"Dotzigen"},"arcs":[[-215,207,211,199,-216]]},{"type":"Polygon","id":387,"properties":{"id":387,"name":"Lengnau (BE)"},"arcs":[[-217,-218,-219,-220,201]]},{"type":"Polygon","id":388,"properties":{"id":388,"name":"Leuzigen"},"arcs":[[-221,193]]},{"type":"Polygon","id":389,"properties":{"id":389,"name":"Meienried"},"arcs":[[-222,-223,-224,208,214]]},{"type":"Polygon","id":390,"properties":{"id":390,"name":"Meinisberg"},"arcs":[[210,-225,-226,216]]},{"type":"Polygon","id":391,"properties":{"id":391,"name":"Oberwil bei Büren"},"arcs":[[204,-227,-228]]},{"type":"Polygon","id":392,"properties":{"id":392,"name":"Pieterlen"},"arcs":[[-229,-230,217,225,-231,188]]},{"type":"Polygon","id":393,"properties":{"id":393,"name":"Rüti bei Büren"},"arcs":[[-232,226,203,-233,195]]},{"type":"Polygon","id":394,"properties":{"id":394,"name":"Wengi"},"arcs":[[42,15,213,-234]]},{"type":"Polygon","id":401,"properties":{"id":401,"name":"Aefligen"},"arcs":[[-235,-236,-237,-238]]},{"type":"Polygon","id":402,"properties":{"id":402,"name":"Alchenstorf"},"arcs":[[-239,-240,-241,-242,-243,-244,-245]]},{"type":"Polygon","id":403,"properties":{"id":403,"name":"Bäriswil"},"arcs":[[-246,-247,-248]]},{"type":"Polygon","id":404,"properties":{"id":404,"name":"Burgdorf"},"arcs":[[-249,-250,-251,-252,-253,-254,-255,-256,-257,-258,-259]]},{"type":"Polygon","id":405,"properties":{"id":405,"name":"Ersigen"},"arcs":[[-260,-261,-262,240,-263]]},{"type":"Polygon","id":406,"properties":{"id":406,"name":"Hasle bei Burgdorf"},"arcs":[[171,-264,-265,-266,255,-267,-268,-269,-270,-271,-272]]},{"type":"MultiPolygon","id":407,"properties":{"id":407,"name":"Heimiswil"},"arcs":[[[-273,266,254,-274,-275]],[[-276,-277]]]},{"type":"Polygon","id":408,"properties":{"id":408,"name":"Hellsau"},"arcs":[[-278,243,-279,-280]]},{"type":"Polygon","id":409,"properties":{"id":409,"name":"Hindelbank"},"arcs":[[-281,-282,-283,-284,-285,258,-286,245]]},{"type":"Polygon","id":410,"properties":{"id":410,"name":"Höchstetten"},"arcs":[[-287,278,242,-288,-289]]},{"type":"Polygon","id":411,"properties":{"id":411,"name":"Kernenried"},"arcs":[[-290,-291,282,-292]]},{"type":"Polygon","id":412,"properties":{"id":412,"name":"Kirchberg (BE)"},"arcs":[[-293,-294,259,-295,-296,252,-297]]},{"type":"Polygon","id":413,"properties":{"id":413,"name":"Koppigen"},"arcs":[[241,261,-298,-299,-300,-301,287]]},{"type":"Polygon","id":414,"properties":{"id":414,"name":"Krauchthal"},"arcs":[[-302,246,285,257,-303,-304,-305,169,135]]},{"type":"Polygon","id":415,"properties":{"id":415,"name":"Lyssach"},"arcs":[[296,251,-306,283,290,-307,-308]]},{"type":"MultiPolygon","id":418,"properties":{"id":418,"name":"Oberburg"},"arcs":[[[-309,302,256,265]],[[-310,263,170,304]],[[-311,249]]]},{"type":"Polygon","id":420,"properties":{"id":420,"name":"Rüdtligen-Alchenflüh"},"arcs":[[307,-312,236,292]]},{"type":"Polygon","id":421,"properties":{"id":421,"name":"Rumendingen"},"arcs":[[262,239,-313,294]]},{"type":"Polygon","id":422,"properties":{"id":422,"name":"Rüti bei Lyssach"},"arcs":[[284,305,250,310,248]]},{"type":"Polygon","id":423,"properties":{"id":423,"name":"Willadingen"},"arcs":[[288,300,-314]]},{"type":"Polygon","id":424,"properties":{"id":424,"name":"Wynigen"},"arcs":[[312,238,-315,-316,102,-317,-318,276,-319,273,253,295]]},{"type":"Polygon","id":431,"properties":{"id":431,"name":"Corgémont"},"arcs":[[-320,-321,-322,-323,-324,-325,-326]]},{"type":"Polygon","id":432,"properties":{"id":432,"name":"Cormoret"},"arcs":[[-327,-328,-329,-330]]},{"type":"Polygon","id":433,"properties":{"id":433,"name":"Cortébert"},"arcs":[[-331,-332,-333,321]]},{"type":"Polygon","id":434,"properties":{"id":434,"name":"Courtelary"},"arcs":[[-334,-335,331,-336,326]]},{"type":"Polygon","id":435,"properties":{"id":435,"name":"La Ferrière"},"arcs":[[-337,-338,-339]]},{"type":"MultiPolygon","id":437,"properties":{"id":437,"name":"Mont-Tramelan"},"arcs":[[[322,332,334,-340,-341]],[[-342,-343,-344]]]},{"type":"Polygon","id":438,"properties":{"id":438,"name":"Orvin"},"arcs":[[-345,-346,-347,186,191,-348,-349,319]]},{"type":"Polygon","id":441,"properties":{"id":441,"name":"Renan (BE)"},"arcs":[[337,-350,-351]]},{"type":"Polygon","id":442,"properties":{"id":442,"name":"Romont (BE)"},"arcs":[[-352,-353,-354,218,229,-355,-356]]},{"type":"Polygon","id":443,"properties":{"id":443,"name":"Saint-Imier"},"arcs":[[-357,-358,-359,-360]]},{"type":"Polygon","id":444,"properties":{"id":444,"name":"Sonceboz-Sombeval"},"arcs":[[325,-361,-362,344]]},{"type":"Polygon","id":445,"properties":{"id":445,"name":"Sonvilier"},"arcs":[[-363,358,-364,349,336]]},{"type":"Polygon","id":446,"properties":{"id":446,"name":"Tramelan"},"arcs":[[-365,341,-366,323,340,-367]]},{"type":"Polygon","id":448,"properties":{"id":448,"name":"Villeret"},"arcs":[[-368,328,-369,-370,356]]},{"type":"Polygon","id":449,"properties":{"id":449,"name":"Sauge"},"arcs":[[346,-371,354,228,187]]},{"type":"Polygon","id":450,"properties":{"id":450,"name":"Péry-La Heutte"},"arcs":[[-372,-373,-374,-375,355,370,345,361]]},{"type":"Polygon","id":491,"properties":{"id":491,"name":"Brüttelen"},"arcs":[[-376,-377,-378,-379,-380,-381]]},{"type":"MultiPolygon","id":492,"properties":{"id":492,"name":"Erlach"},"arcs":[[[-382,-383,-384,-385,-386,-387,-388]],[[-389,-390]]]},{"type":"Polygon","id":493,"properties":{"id":493,"name":"Finsterhennen"},"arcs":[[380,-391,-392,21,-393]]},{"type":"Polygon","id":494,"properties":{"id":494,"name":"Gals"},"arcs":[[388,-394,-395,-396,382,-397]]},{"type":"Polygon","id":495,"properties":{"id":495,"name":"Gampelen"},"arcs":[[394,-398,-399,-400]]},{"type":"Polygon","id":496,"properties":{"id":496,"name":"Ins"},"arcs":[[387,-401,377,-402,-403,398,-404]]},{"type":"Polygon","id":497,"properties":{"id":497,"name":"Lüscherz"},"arcs":[[-405,390,379,-406,-407,-408]]},{"type":"Polygon","id":498,"properties":{"id":498,"name":"Müntschemier"},"arcs":[[401,376,-409,-410]]},{"type":"Polygon","id":499,"properties":{"id":499,"name":"Siselen"},"arcs":[[-411,-412,8,22,391,404]]},{"type":"Polygon","id":500,"properties":{"id":500,"name":"Treiten"},"arcs":[[392,20,-413,408,375]]},{"type":"Polygon","id":501,"properties":{"id":501,"name":"Tschugg"},"arcs":[[396,381,403,397,393,389]]},{"type":"Polygon","id":502,"properties":{"id":502,"name":"Vinelz"},"arcs":[[378,400,386,-414,405]]},{"type":"Polygon","id":533,"properties":{"id":533,"name":"Bätterkinden"},"arcs":[[-415,-416,-417,234,-418,-419]]},{"type":"Polygon","id":535,"properties":{"id":535,"name":"Deisswil bei Münchenbuchsee"},"arcs":[[-420,-421,-422,-423,47]]},{"type":"Polygon","id":538,"properties":{"id":538,"name":"Fraubrunnen"},"arcs":[[417,237,311,306,289,-424,-425,-426,-427]]},{"type":"MultiPolygon","id":540,"properties":{"id":540,"name":"Jegenstorf"},"arcs":[[[291,281,-428,-429,-430,420,-431,-432,423]],[[425,-433,44,-434]]]},{"type":"Polygon","id":541,"properties":{"id":541,"name":"Iffwil"},"arcs":[[-435,45,432,424,431]]},{"type":"Polygon","id":543,"properties":{"id":543,"name":"Mattstetten"},"arcs":[[142,-436,427,280,247,301]]},{"type":"Polygon","id":544,"properties":{"id":544,"name":"Moosseedorf"},"arcs":[[140,-437,-438,-439]]},{"type":"Polygon","id":546,"properties":{"id":546,"name":"Münchenbuchsee"},"arcs":[[147,52,48,422,-440,436,178,175]]},{"type":"Polygon","id":551,"properties":{"id":551,"name":"Urtenen-Schönbühl"},"arcs":[[438,-441,428,435,141]]},{"type":"Polygon","id":552,"properties":{"id":552,"name":"Utzenstorf"},"arcs":[[297,260,293,235,416,-442,-443]]},{"type":"Polygon","id":553,"properties":{"id":553,"name":"Wiggiswil"},"arcs":[[429,440,437,439,421]]},{"type":"Polygon","id":554,"properties":{"id":554,"name":"Wiler bei Utzenstorf"},"arcs":[[441,415,-444]]},{"type":"Polygon","id":556,"properties":{"id":556,"name":"Zielebach"},"arcs":[[-445,298,442,443,414]]},{"type":"Polygon","id":557,"properties":{"id":557,"name":"Zuzwil (BE)"},"arcs":[[46,434,430,419]]},{"type":"Polygon","id":561,"properties":{"id":561,"name":"Adelboden"},"arcs":[[-446,-447,-448,-449,-450,-451]]},{"type":"Polygon","id":562,"properties":{"id":562,"name":"Aeschi bei Spiez"},"arcs":[[-452,-453,-454,-455,-456,-457,-458]]},{"type":"Polygon","id":563,"properties":{"id":563,"name":"Frutigen"},"arcs":[[-459,-460,445,-461,-462]]},{"type":"Polygon","id":564,"properties":{"id":564,"name":"Kandergrund"},"arcs":[[458,-463,-464]]},{"type":"Polygon","id":565,"properties":{"id":565,"name":"Kandersteg"},"arcs":[[-465,446,459,463,-466,-467]]},{"type":"Polygon","id":566,"properties":{"id":566,"name":"Krattigen"},"arcs":[[457,-468,-469,-470]]},{"type":"Polygon","id":567,"properties":{"id":567,"name":"Reichenbach im Kandertal"},"arcs":[[-471,-472,454,-473,465,462,461]]},{"type":"Polygon","id":571,"properties":{"id":571,"name":"Beatenberg"},"arcs":[[-474,-475,-476,-477,-478,-479]]},{"type":"Polygon","id":572,"properties":{"id":572,"name":"Bönigen"},"arcs":[[-480,-481,-482,-483,-484,-485,-486,-487]]},{"type":"Polygon","id":573,"properties":{"id":573,"name":"Brienz (BE)"},"arcs":[[-488,-489,-490,-491,-492,-493,-494,-495,-496,-497]]},{"type":"MultiPolygon","id":574,"properties":{"id":574,"name":"Brienzwiler"},"arcs":[[[496,-498]],[[-499,-500,494,-501]]]},{"type":"Polygon","id":575,"properties":{"id":575,"name":"Därligen"},"arcs":[[-502,-503,-504,-505,-506,-507]]},{"type":"Polygon","id":576,"properties":{"id":576,"name":"Grindelwald"},"arcs":[[-508,-509,-510,-511,-512,-513,-514,487]]},{"type":"Polygon","id":577,"properties":{"id":577,"name":"Gsteigwiler"},"arcs":[[-515,-516,-517,479]]},{"type":"Polygon","id":578,"properties":{"id":578,"name":"Gündlischwand"},"arcs":[[-518,-519,-520,514,486,-521]]},{"type":"Polygon","id":579,"properties":{"id":579,"name":"Habkern"},"arcs":[[-522,-523,473,-524,-525,-526,-527,-528]]},{"type":"Polygon","id":580,"properties":{"id":580,"name":"Hofstetten bei Brienz"},"arcs":[[-529,500,493,-530]]},{"type":"Polygon","id":581,"properties":{"id":581,"name":"Interlaken"},"arcs":[[-531,483,-532,501,-533,-534,-535]]},{"type":"MultiPolygon","id":582,"properties":{"id":582,"name":"Iseltwald"},"arcs":[[[520,485,-536,488,513,-537]]]},{"type":"Polygon","id":584,"properties":{"id":584,"name":"Lauterbrunnen"},"arcs":[[466,472,453,-538,-539,518,-540,511,-541]]},{"type":"Polygon","id":585,"properties":{"id":585,"name":"Leissigen"},"arcs":[[469,-542,505,-543,451]]},{"type":"Polygon","id":586,"properties":{"id":586,"name":"Lütschental"},"arcs":[[536,512,539,517]]},{"type":"MultiPolygon","id":587,"properties":{"id":587,"name":"Matten bei Interlaken"},"arcs":[[[531,482,-544,502]],[[-545,480,516]]]},{"type":"Polygon","id":588,"properties":{"id":588,"name":"Niederried bei Interlaken"},"arcs":[[527,-546,-547,-548]]},{"type":"Polygon","id":589,"properties":{"id":589,"name":"Oberried am Brienzersee"},"arcs":[[545,526,-549,490,-550]]},{"type":"Polygon","id":590,"properties":{"id":590,"name":"Ringgenberg (BE)"},"arcs":[[534,-551,521,547,-552]]},{"type":"Polygon","id":591,"properties":{"id":591,"name":"Saxeten"},"arcs":[[542,504,-553,537,452]]},{"type":"Polygon","id":592,"properties":{"id":592,"name":"Schwanden bei Brienz"},"arcs":[[529,492,-554]]},{"type":"Polygon","id":593,"properties":{"id":593,"name":"Unterseen"},"arcs":[[-555,474,522,550,533]]},{"type":"Polygon","id":594,"properties":{"id":594,"name":"Wilderswil"},"arcs":[[538,552,503,543,481,544,515,519]]},{"type":"Polygon","id":602,"properties":{"id":602,"name":"Arni (BE)"},"arcs":[[-556,-557,-558,-559,-560,-561]]},{"type":"Polygon","id":603,"properties":{"id":603,"name":"Biglen"},"arcs":[[-562,-563,557,-564]]},{"type":"Polygon","id":605,"properties":{"id":605,"name":"Bowil"},"arcs":[[-565,-566,-567,-568,-569,-570]]},{"type":"Polygon","id":606,"properties":{"id":606,"name":"Brenzikofen"},"arcs":[[-571,-572,-573,-574,-575]]},{"type":"Polygon","id":607,"properties":{"id":607,"name":"Freimettigen"},"arcs":[[-576,-577,-578,-579,-580]]},{"type":"Polygon","id":608,"properties":{"id":608,"name":"Grosshöchstetten"},"arcs":[[563,556,-581,-582,-583,-584,-585,-586]]},{"type":"Polygon","id":609,"properties":{"id":609,"name":"Häutligen"},"arcs":[[-587,-588,577,-589,-590]]},{"type":"Polygon","id":610,"properties":{"id":610,"name":"Herbligen"},"arcs":[[-591,-592,-593,571]]},{"type":"Polygon","id":611,"properties":{"id":611,"name":"Kiesen"},"arcs":[[-594,-595,-596,-597,-598]]},{"type":"Polygon","id":612,"properties":{"id":612,"name":"Konolfingen"},"arcs":[[578,587,-599,583,-600,-601]]},{"type":"Polygon","id":613,"properties":{"id":613,"name":"Landiswil"},"arcs":[[-602,-603,-604,-605,559]]},{"type":"Polygon","id":614,"properties":{"id":614,"name":"Linden"},"arcs":[[569,-606,-607,-608,575,-609,-610]]},{"type":"Polygon","id":615,"properties":{"id":615,"name":"Mirchel"},"arcs":[[-611,-612,-613,599,582]]},{"type":"Polygon","id":616,"properties":{"id":616,"name":"Münsingen"},"arcs":[[-614,-615,-616,584,598,586,-617,-618]]},{"type":"Polygon","id":617,"properties":{"id":617,"name":"Niederhünigen"},"arcs":[[579,600,612,-619,608]]},{"type":"Polygon","id":619,"properties":{"id":619,"name":"Oberdiessbach"},"arcs":[[-620,572,592,-621,588,576,607,-622]]},{"type":"Polygon","id":620,"properties":{"id":620,"name":"Oberthal"},"arcs":[[-623,-624,566,-625,580,555]]},{"type":"Polygon","id":622,"properties":{"id":622,"name":"Oppligen"},"arcs":[[594,-626,590,570,-627]]},{"type":"Polygon","id":623,"properties":{"id":623,"name":"Rubigen"},"arcs":[[-628,-629,-630,614]]},{"type":"Polygon","id":626,"properties":{"id":626,"name":"Walkringen"},"arcs":[[172,271,-631,601,558,562,-632]]},{"type":"Polygon","id":627,"properties":{"id":627,"name":"Worb"},"arcs":[[631,561,585,615,629,-633,156,168]]},{"type":"Polygon","id":628,"properties":{"id":628,"name":"Zäziwil"},"arcs":[[565,-634,610,581,624]]},{"type":"Polygon","id":629,"properties":{"id":629,"name":"Oberhünigen"},"arcs":[[609,618,611,633,564]]},{"type":"Polygon","id":630,"properties":{"id":630,"name":"Allmendingen"},"arcs":[[632,628,-635,157]]},{"type":"Polygon","id":632,"properties":{"id":632,"name":"Wichtrach"},"arcs":[[591,625,593,-636,-637,-638,616,589,620]]},{"type":"MultiPolygon","id":662,"properties":{"id":662,"name":"Ferenbalm"},"arcs":[[[-639,-640,-641,-642,-643,-644,-645]],[[-646,-647,-648]]]},{"type":"Polygon","id":663,"properties":{"id":663,"name":"Frauenkappelen"},"arcs":[[126,-649,173]]},{"type":"Polygon","id":665,"properties":{"id":665,"name":"Gurbrü"},"arcs":[[-650,639,-651]]},{"type":"Polygon","id":666,"properties":{"id":666,"name":"Kriechenwil"},"arcs":[[644,-652,646,-653,-654]]},{"type":"Polygon","id":667,"properties":{"id":667,"name":"Laupen"},"arcs":[[652,645,-655,642,-656,-657,-658]]},{"type":"Polygon","id":668,"properties":{"id":668,"name":"Mühleberg"},"arcs":[[174,648,125,-659,655,641,-660,17,39]]},{"type":"Polygon","id":669,"properties":{"id":669,"name":"Münchenwiler"},"arcs":[[-661]]},{"type":"Polygon","id":670,"properties":{"id":670,"name":"Neuenegg"},"arcs":[[154,-662,656,658,124]]},{"type":"Polygon","id":671,"properties":{"id":671,"name":"Wileroltigen"},"arcs":[[-663,18,659,640,649]]},{"type":"Polygon","id":681,"properties":{"id":681,"name":"Belprahon"},"arcs":[[-664,-665,-666,-667]]},{"type":"Polygon","id":683,"properties":{"id":683,"name":"Champoz"},"arcs":[[-668,-669,-670,-671,-672,-673]]},{"type":"Polygon","id":687,"properties":{"id":687,"name":"Corcelles (BE)"},"arcs":[[-674,-675,-676,-677]]},{"type":"Polygon","id":690,"properties":{"id":690,"name":"Court"},"arcs":[[-678,-679,-680,352,-681,667]]},{"type":"Polygon","id":691,"properties":{"id":691,"name":"Crémines"},"arcs":[[674,-682,-683,-684]]},{"type":"Polygon","id":692,"properties":{"id":692,"name":"Eschert"},"arcs":[[-685,665,-686,-687,678]]},{"type":"Polygon","id":694,"properties":{"id":694,"name":"Grandval"},"arcs":[[-688,685,664,-689,-690,682]]},{"type":"Polygon","id":696,"properties":{"id":696,"name":"Loveresse"},"arcs":[[-691,-692,-693,-694]]},{"type":"Polygon","id":700,"properties":{"id":700,"name":"Moutier"},"arcs":[[672,-695,-696,-697,666,684,677]]},{"type":"Polygon","id":701,"properties":{"id":701,"name":"Perrefitte"},"arcs":[[-698,-699,694,671]]},{"type":"Polygon","id":703,"properties":{"id":703,"name":"Reconvilier"},"arcs":[[690,-700,372,-701,-702,-703]]},{"type":"Polygon","id":704,"properties":{"id":704,"name":"Roches (BE)"},"arcs":[[696,-704,688,663]]},{"type":"Polygon","id":706,"properties":{"id":706,"name":"Saicourt"},"arcs":[[-705,701,-706,342,364,-707,-708]]},{"type":"Polygon","id":707,"properties":{"id":707,"name":"Saules (BE)"},"arcs":[[702,704,-709,691]]},{"type":"Polygon","id":708,"properties":{"id":708,"name":"Schelten"},"arcs":[[-710]]},{"type":"Polygon","id":709,"properties":{"id":709,"name":"Seehof"},"arcs":[[-711,676,-712]]},{"type":"Polygon","id":711,"properties":{"id":711,"name":"Sorvilier"},"arcs":[[374,-713,668,680,351]]},{"type":"Polygon","id":713,"properties":{"id":713,"name":"Tavannes"},"arcs":[[360,324,365,343,705,700,371]]},{"type":"Polygon","id":715,"properties":{"id":715,"name":"Rebévelier"},"arcs":[[-714,-715]]},{"type":"Polygon","id":716,"properties":{"id":716,"name":"Petit-Val"},"arcs":[[707,-716,714,-717,697,670,-718,692,708]]},{"type":"Polygon","id":717,"properties":{"id":717,"name":"Valbirse"},"arcs":[[693,717,669,712,373,699]]},{"type":"Polygon","id":723,"properties":{"id":723,"name":"La Neuveville"},"arcs":[[-719,-720,-721]]},{"type":"Polygon","id":724,"properties":{"id":724,"name":"Nods"},"arcs":[[348,-722,-723,368,327,335,330,320]]},{"type":"Polygon","id":726,"properties":{"id":726,"name":"Plateau de Diesse"},"arcs":[[-724,721,347,190,-725,-726,719]]},{"type":"Polygon","id":731,"properties":{"id":731,"name":"Aegerten"},"arcs":[[-727,-728,-729,-730,-731]]},{"type":"Polygon","id":732,"properties":{"id":732,"name":"Bellmund"},"arcs":[[-732,-733,-734,-735,-736,-737]]},{"type":"Polygon","id":733,"properties":{"id":733,"name":"Brügg"},"arcs":[[-738,180,-739,-740,729]]},{"type":"Polygon","id":734,"properties":{"id":734,"name":"Bühl"},"arcs":[[-741,-742,24,-743]]},{"type":"Polygon","id":735,"properties":{"id":735,"name":"Epsach"},"arcs":[[-744,740,-745,-746,-747]]},{"type":"Polygon","id":736,"properties":{"id":736,"name":"Hagneck"},"arcs":[[-748,-749,410,407,-750]]},{"type":"Polygon","id":737,"properties":{"id":737,"name":"Hermrigen"},"arcs":[[-751,25,741,743,-752,-753,734]]},{"type":"Polygon","id":738,"properties":{"id":738,"name":"Jens"},"arcs":[[-754,27,-755,732,-756,727,-757]]},{"type":"Polygon","id":739,"properties":{"id":739,"name":"Ipsach"},"arcs":[[-758,-759,-760,736,-761]]},{"type":"Polygon","id":740,"properties":{"id":740,"name":"Ligerz"},"arcs":[[-762,720,725,-763]]},{"type":"Polygon","id":741,"properties":{"id":741,"name":"Merzligen"},"arcs":[[750,733,754,26]]},{"type":"Polygon","id":742,"properties":{"id":742,"name":"Mörigen"},"arcs":[[746,-764,-765,-766,751]]},{"type":"Polygon","id":743,"properties":{"id":743,"name":"Nidau"},"arcs":[[-767,758,-768,182]]},{"type":"Polygon","id":744,"properties":{"id":744,"name":"Orpund"},"arcs":[[-769,-770,-771,738,179]]},{"type":"Polygon","id":745,"properties":{"id":745,"name":"Port"},"arcs":[[759,766,181,737,728,755,731]]},{"type":"Polygon","id":746,"properties":{"id":746,"name":"Safnern"},"arcs":[[768,189,230,224,209,223,-772]]},{"type":"Polygon","id":747,"properties":{"id":747,"name":"Scheuren"},"arcs":[[771,222,-773,769]]},{"type":"Polygon","id":748,"properties":{"id":748,"name":"Schwadernau"},"arcs":[[215,198,-774,730,739,770,772,221]]},{"type":"Polygon","id":749,"properties":{"id":749,"name":"Studen (BE)"},"arcs":[[756,726,773,197,33,-775]]},{"type":"Polygon","id":750,"properties":{"id":750,"name":"Sutz-Lattrigen"},"arcs":[[760,735,752,765,-776]]},{"type":"Polygon","id":751,"properties":{"id":751,"name":"Täuffelen"},"arcs":[[-777,763,745,-778,747]]},{"type":"Polygon","id":754,"properties":{"id":754,"name":"Walperswil"},"arcs":[[9,411,748,777,744,742,23]]},{"type":"Polygon","id":755,"properties":{"id":755,"name":"Worben"},"arcs":[[774,32,28,753]]},{"type":"MultiPolygon","id":756,"properties":{"id":756,"name":"Twann-Tüscherz"},"arcs":[[[-779,762,724,192,184]],[[384,-780]]]},{"type":"Polygon","id":761,"properties":{"id":761,"name":"Därstetten"},"arcs":[[-781,-782,-783,-784,-785,-786,-787,-788]]},{"type":"Polygon","id":762,"properties":{"id":762,"name":"Diemtigen"},"arcs":[[-789,-790,-791,-792,786,-793,-794,470,460,450]]},{"type":"Polygon","id":763,"properties":{"id":763,"name":"Erlenbach im Simmental"},"arcs":[[792,785,-795,-796,-797]]},{"type":"Polygon","id":766,"properties":{"id":766,"name":"Oberwil im Simmental"},"arcs":[[787,791,-798,-799,-800,-801]]},{"type":"Polygon","id":767,"properties":{"id":767,"name":"Reutigen"},"arcs":[[-802,-803,-804,795,-805,-806]]},{"type":"Polygon","id":768,"properties":{"id":768,"name":"Spiez"},"arcs":[[-807,-808,467,456,-809,802]]},{"type":"Polygon","id":769,"properties":{"id":769,"name":"Wimmis"},"arcs":[[808,455,471,793,796,803]]},{"type":"Polygon","id":770,"properties":{"id":770,"name":"Stocken-Höfen"},"arcs":[[-810,804,794,784,-811,-812]]},{"type":"Polygon","id":782,"properties":{"id":782,"name":"Guttannen"},"arcs":[[-813,-814,509]]},{"type":"Polygon","id":783,"properties":{"id":783,"name":"Hasliberg"},"arcs":[[-815,-816,-817]]},{"type":"Polygon","id":784,"properties":{"id":784,"name":"Innertkirchen"},"arcs":[[812,508,-818,-819,816,-820]]},{"type":"Polygon","id":785,"properties":{"id":785,"name":"Meiringen"},"arcs":[[497,495,499,-821,814,818,-822,507]]},{"type":"Polygon","id":786,"properties":{"id":786,"name":"Schattenhalb"},"arcs":[[817,821]]},{"type":"Polygon","id":791,"properties":{"id":791,"name":"Boltigen"},"arcs":[[-823,-824,-825,797,790]]},{"type":"Polygon","id":792,"properties":{"id":792,"name":"Lenk"},"arcs":[[-826,-827,448,-828,-829]]},{"type":"Polygon","id":793,"properties":{"id":793,"name":"St. Stephan"},"arcs":[[-830,788,449,826,-831]]},{"type":"Polygon","id":794,"properties":{"id":794,"name":"Zweisimmen"},"arcs":[[789,829,-832,822]]},{"type":"Polygon","id":841,"properties":{"id":841,"name":"Gsteig"},"arcs":[[-833,-834,-835]]},{"type":"Polygon","id":842,"properties":{"id":842,"name":"Lauenen"},"arcs":[[828,-836,833,-837]]},{"type":"Polygon","id":843,"properties":{"id":843,"name":"Saanen"},"arcs":[[836,832,-838,823,831,830,825]]},{"type":"Polygon","id":852,"properties":{"id":852,"name":"Guggisberg"},"arcs":[[-839,-840,799,-841]]},{"type":"Polygon","id":853,"properties":{"id":853,"name":"Rüschegg"},"arcs":[[800,839,-842,-843,-844,-845,780]]},{"type":"Polygon","id":855,"properties":{"id":855,"name":"Schwarzenburg"},"arcs":[[-846,152,163,-847,841,838]]},{"type":"Polygon","id":861,"properties":{"id":861,"name":"Belp"},"arcs":[[-848,-849,-850,-851,-852,158,634,627,613]]},{"type":"Polygon","id":863,"properties":{"id":863,"name":"Burgistein"},"arcs":[[-853,-854,-855,-856,-857,-858]]},{"type":"Polygon","id":866,"properties":{"id":866,"name":"Gerzensee"},"arcs":[[-859,847,617,637]]},{"type":"Polygon","id":867,"properties":{"id":867,"name":"Gurzelen"},"arcs":[[855,-860,-861,-862,-863]]},{"type":"Polygon","id":868,"properties":{"id":868,"name":"Jaberg"},"arcs":[[597,-864,-865,635]]},{"type":"Polygon","id":869,"properties":{"id":869,"name":"Kaufdorf"},"arcs":[[-866,-867,-868,-869]]},{"type":"Polygon","id":870,"properties":{"id":870,"name":"Kehrsatz"},"arcs":[[-870,149,159,851]]},{"type":"Polygon","id":872,"properties":{"id":872,"name":"Kirchdorf (BE)"},"arcs":[[636,864,-871,-872,-873,853,-874,-875,865,-876,848,858]]},{"type":"Polygon","id":877,"properties":{"id":877,"name":"Niedermuhlern"},"arcs":[[165,-877,-878,-879]]},{"type":"Polygon","id":879,"properties":{"id":879,"name":"Riggisberg"},"arcs":[[866,874,-880,857,-881,-882,-883,843,-884]]},{"type":"MultiPolygon","id":880,"properties":{"id":880,"name":"Rüeggisberg"},"arcs":[[[883,842,846,162,878,-885,867]],[[844,882,-886,781]]]},{"type":"Polygon","id":883,"properties":{"id":883,"name":"Seftigen"},"arcs":[[872,-887,859,854]]},{"type":"Polygon","id":884,"properties":{"id":884,"name":"Toffen"},"arcs":[[868,884,877,-888,849,875]]},{"type":"Polygon","id":885,"properties":{"id":885,"name":"Uttigen"},"arcs":[[870,863,596,-889,-890]]},{"type":"Polygon","id":886,"properties":{"id":886,"name":"Wattenwil"},"arcs":[[862,-891,-892,880,856]]},{"type":"Polygon","id":888,"properties":{"id":888,"name":"Wald (BE)"},"arcs":[[850,887,876,164,150,869]]},{"type":"Polygon","id":889,"properties":{"id":889,"name":"Thurnen"},"arcs":[[879,873,852]]},{"type":"Polygon","id":901,"properties":{"id":901,"name":"Eggiwil"},"arcs":[[-893,-894,-895,-896,-897,-898,-899]]},{"type":"Polygon","id":902,"properties":{"id":902,"name":"Langnau im Emmental"},"arcs":[[-900,-901,-902,-903,-904,893,-905]]},{"type":"Polygon","id":903,"properties":{"id":903,"name":"Lauperswil"},"arcs":[[-906,622,560,604,-907,-908,899]]},{"type":"Polygon","id":904,"properties":{"id":904,"name":"Röthenbach im Emmental"},"arcs":[[-909,-910,-911,605,568,-912,898,-913,-914]]},{"type":"Polygon","id":905,"properties":{"id":905,"name":"Rüderswil"},"arcs":[[603,-915,269,-916,-917,906]]},{"type":"Polygon","id":906,"properties":{"id":906,"name":"Schangnau"},"arcs":[[524,-918,912,897,-919]]},{"type":"Polygon","id":907,"properties":{"id":907,"name":"Signau"},"arcs":[[911,567,623,905,904,892]]},{"type":"Polygon","id":908,"properties":{"id":908,"name":"Trub"},"arcs":[[-920,895,-921,902,-922]]},{"type":"Polygon","id":909,"properties":{"id":909,"name":"Trubschachen"},"arcs":[[920,894,903]]},{"type":"Polygon","id":921,"properties":{"id":921,"name":"Amsoldingen"},"arcs":[[805,809,-923,-924,-925]]},{"type":"Polygon","id":922,"properties":{"id":922,"name":"Blumenstein"},"arcs":[[885,881,891,-926,-927,-928,782]]},{"type":"Polygon","id":923,"properties":{"id":923,"name":"Buchholterberg"},"arcs":[[-929,-930,621,606,910,-931]]},{"type":"Polygon","id":924,"properties":{"id":924,"name":"Eriz"},"arcs":[[913,917,523,478,-932,-933,-934]]},{"type":"Polygon","id":925,"properties":{"id":925,"name":"Fahrni"},"arcs":[[929,-935,-936,-937,-938,573,619]]},{"type":"Polygon","id":927,"properties":{"id":927,"name":"Heiligenschwendi"},"arcs":[[-939,-940,-941,-942,-943,-944]]},{"type":"Polygon","id":928,"properties":{"id":928,"name":"Heimberg"},"arcs":[[-945,888,595,626,574,937,-946,-947]]},{"type":"Polygon","id":929,"properties":{"id":929,"name":"Hilterfingen"},"arcs":[[-948,941,-949,-950]]},{"type":"Polygon","id":931,"properties":{"id":931,"name":"Homberg"},"arcs":[[943,-951,-952,935,-953,-954,-955]]},{"type":"MultiPolygon","id":932,"properties":{"id":932,"name":"Horrenbach-Buchen"},"arcs":[[[-956,931,477,-957]],[[953,-958,-959,-960]]]},{"type":"Polygon","id":934,"properties":{"id":934,"name":"Oberhofen am Thunersee"},"arcs":[[940,-961,-962,948]]},{"type":"Polygon","id":935,"properties":{"id":935,"name":"Oberlangenegg"},"arcs":[[933,-963,958,-964,-965,908]]},{"type":"Polygon","id":936,"properties":{"id":936,"name":"Pohlern"},"arcs":[[783,927,-966,810]]},{"type":"Polygon","id":938,"properties":{"id":938,"name":"Sigriswil"},"arcs":[[956,476,-967,960,939,-968]]},{"type":"Polygon","id":939,"properties":{"id":939,"name":"Steffisburg"},"arcs":[[951,-969,945,936]]},{"type":"Polygon","id":940,"properties":{"id":940,"name":"Teuffenthal (BE)"},"arcs":[[954,959,962,932,955,967,938]]},{"type":"Polygon","id":941,"properties":{"id":941,"name":"Thierachern"},"arcs":[[-970,-971,923,-972,-973]]},{"type":"Polygon","id":942,"properties":{"id":942,"name":"Thun"},"arcs":[[946,968,950,942,947,-974,806,801,924,970,-975]]},{"type":"Polygon","id":943,"properties":{"id":943,"name":"Uebeschi"},"arcs":[[971,922,811,965,926,-976]]},{"type":"Polygon","id":944,"properties":{"id":944,"name":"Uetendorf"},"arcs":[[-977,860,886,871,889,944,974,969]]},{"type":"Polygon","id":945,"properties":{"id":945,"name":"Unterlangenegg"},"arcs":[[-978,963,957,952,934,928]]},{"type":"Polygon","id":946,"properties":{"id":946,"name":"Wachseldorn"},"arcs":[[930,909,964,977]]},{"type":"Polygon","id":948,"properties":{"id":948,"name":"Forst-Längenbühl"},"arcs":[[972,975,925,890,861,976]]},{"type":"Polygon","id":951,"properties":{"id":951,"name":"Affoltern im Emmental"},"arcs":[[-979,-980,274,318,275,317,-981,-982]]},{"type":"Polygon","id":952,"properties":{"id":952,"name":"Dürrenroth"},"arcs":[[981,-983,111,-984,-985,-986]]},{"type":"Polygon","id":953,"properties":{"id":953,"name":"Eriswil"},"arcs":[[-987,-988,-989,-990]]},{"type":"Polygon","id":954,"properties":{"id":954,"name":"Huttwil"},"arcs":[[84,-991,987,-992,983,110,109,61]]},{"type":"MultiPolygon","id":955,"properties":{"id":955,"name":"Lützelflüh"},"arcs":[[[-993,915,268,-994,-995]],[[914,602,630,270]],[[264,309,303,308]]]},{"type":"Polygon","id":956,"properties":{"id":956,"name":"Rüegsau"},"arcs":[[-996,993,267,272,979]]},{"type":"Polygon","id":957,"properties":{"id":957,"name":"Sumiswald"},"arcs":[[994,995,978,985,-997,989,-998,921,901,-999]]},{"type":"Polygon","id":958,"properties":{"id":958,"name":"Trachselwald"},"arcs":[[998,900,907,916,992]]},{"type":"Polygon","id":959,"properties":{"id":959,"name":"Walterswil (BE)"},"arcs":[[105,122,112,982,980,316]]},{"type":"Polygon","id":960,"properties":{"id":960,"name":"Wyssachen"},"arcs":[[996,984,991,986]]},{"type":"Polygon","id":971,"properties":{"id":971,"name":"Attiswil"},"arcs":[[-1000,-1001,-1002,-1003,-1004]]},{"type":"Polygon","id":972,"properties":{"id":972,"name":"Berken"},"arcs":[[-1005,-1006,67,-1007,-1008]]},{"type":"Polygon","id":973,"properties":{"id":973,"name":"Bettenhausen"},"arcs":[[-1009,-1010,-1011,-1012,-1013]]},{"type":"Polygon","id":975,"properties":{"id":975,"name":"Farnern"},"arcs":[[999,-1014,-1015]]},{"type":"Polygon","id":976,"properties":{"id":976,"name":"Graben"},"arcs":[[66,56,118,-1016,-1017,1006]]},{"type":"Polygon","id":977,"properties":{"id":977,"name":"Heimenhausen"},"arcs":[[-1018,1007,1016,-1019,-1020,-1021,-1022]]},{"type":"Polygon","id":979,"properties":{"id":979,"name":"Herzogenbuchsee"},"arcs":[[120,-1023,1009,-1024,-1025,-1026,-1027,1018,1015]]},{"type":"Polygon","id":980,"properties":{"id":980,"name":"Inkwil"},"arcs":[[1020,-1028,-1029,-1030]]},{"type":"Polygon","id":981,"properties":{"id":981,"name":"Niederbipp"},"arcs":[[70,-1031,-1032,-1033,115]]},{"type":"Polygon","id":982,"properties":{"id":982,"name":"Niederönz"},"arcs":[[1019,1026,-1034,1027]]},{"type":"Polygon","id":983,"properties":{"id":983,"name":"Oberbipp"},"arcs":[[-1035,-1036,1030,69,-1037]]},{"type":"Polygon","id":985,"properties":{"id":985,"name":"Ochlenberg"},"arcs":[[1011,-1038,72,114,98,121,103,315,-1039]]},{"type":"Polygon","id":987,"properties":{"id":987,"name":"Rumisberg"},"arcs":[[1035,-1040,1000,1014,-1041,1031]]},{"type":"Polygon","id":988,"properties":{"id":988,"name":"Seeberg"},"arcs":[[1012,1038,314,244,277,-1042,1024,-1043]]},{"type":"Polygon","id":989,"properties":{"id":989,"name":"Thörigen"},"arcs":[[73,1037,1010,1022,119]]},{"type":"Polygon","id":990,"properties":{"id":990,"name":"Walliswil bei Niederbipp"},"arcs":[[1036,68,1005,-1044,-1045]]},{"type":"Polygon","id":991,"properties":{"id":991,"name":"Walliswil bei Wangen"},"arcs":[[1017,-1046,-1047,1043,1004]]},{"type":"Polygon","id":992,"properties":{"id":992,"name":"Wangen an der Aare"},"arcs":[[1002,-1048,1045,1021,1029,-1049]]},{"type":"Polygon","id":995,"properties":{"id":995,"name":"Wiedlisbach"},"arcs":[[1044,1046,1047,1001,1039,1034]]}]}},"arcs":[[[27823,71483],[-171,-27],[-27,192],[-128,-30],[24,187],[-309,226],[-113,-209],[-173,0],[82,193],[-273,116]],[[26088,68775],[-177,187],[-86,314],[187,34],[162,-147],[75,197],[259,217],[527,294],[457,412],[-5,163],[-152,227],[115,201],[378,291],[-5,318]],[[25161,68738],[333,246],[237,-33],[357,-176]],[[24714,70859],[-52,-113],[183,-70],[-25,-102],[362,-180],[204,-212],[-203,-866],[-22,-578]],[[26735,72131],[-667,-317],[-84,177],[-372,-296],[-99,-324],[-315,-297],[-199,136],[-152,-209],[192,-94],[-109,-153],[-216,105]],[[24714,70859],[-456,284]],[[24474,68014],[66,189],[262,282],[359,253]],[[21863,68975],[661,612],[199,21],[102,-346],[294,133],[406,-359],[53,56],[339,-360],[-57,-103],[-6,-384],[141,-249],[184,149],[295,-131]],[[22033,69911],[-418,-284],[235,-366],[-106,-102],[119,-184]],[[24258,71143],[-119,-290],[124,-195],[-1616,-14],[-226,-687],[-388,-46]],[[31862,71475],[32,139],[476,75],[146,467],[90,54],[97,529],[130,420],[7,244]],[[29842,70661],[118,-39],[474,18],[194,66],[-168,136],[-107,251],[66,194],[237,155],[221,-14],[54,-104],[931,151]],[[29055,72170],[198,-396],[-240,-157],[344,-375],[-18,-343],[390,-4],[-14,-162],[127,-72]],[[30504,74997],[52,-211],[-289,24],[-96,-331],[-185,-253],[-153,-78],[42,-150],[-388,-123],[-87,-163],[11,-481],[-89,-117],[-34,-332],[-138,-252],[-95,-360]],[[31540,74897],[-64,194],[-155,144],[-214,5],[-365,-181],[-238,-62]],[[32840,73403],[-233,275],[-19,608],[-121,36],[-585,-281],[-287,53],[-238,388],[200,276],[-17,139]],[[24938,64086],[25,253],[-178,277],[-330,234],[-238,425],[-571,668],[-94,482],[316,262],[565,177],[234,159],[85,278],[-61,243],[-217,470]],[[24612,64025],[326,61]],[[22987,64195],[95,-72],[147,160],[438,31],[79,-125],[277,138],[126,148],[158,-21],[0,-330],[206,90],[99,-189]],[[19737,65539],[1010,564],[122,31],[-23,196],[274,-48],[277,452],[322,-229],[173,280],[170,-157],[108,104],[361,-688],[158,-12],[41,-215],[-264,-373],[233,-75],[557,-556],[47,-212],[-234,-224],[-82,-182]],[[19781,67042],[-133,-158],[82,-191],[-472,-590],[479,-564]],[[20818,67646],[-442,-399],[-396,-432],[-199,227]],[[21863,68975],[-511,-482],[160,-222],[-694,-625]],[[24227,71616],[-135,-348],[166,-125]],[[24795,73022],[-568,-1406]],[[24979,73481],[-184,-459]],[[25439,74345],[-276,-407],[-184,-457]],[[26361,75358],[-137,122],[-785,-1135]],[[27812,75236],[-152,350],[-32,221],[-350,-181],[-436,-378],[-143,1],[-139,-154],[-259,178],[60,85]],[[26735,72131],[-67,455],[89,53],[146,345],[49,259],[-52,284],[114,351],[-64,130],[249,245],[613,983]],[[30504,74997],[-155,319]],[[27823,71483],[182,32],[159,419],[791,246],[100,-10]],[[28157,76405],[-159,-501],[11,-320],[-197,-348]],[[28323,76919],[-166,-514]],[[30349,75316],[-240,52],[-318,-107],[-206,114],[-200,237],[-2,559],[67,115],[-148,227],[66,140],[-184,52],[-328,-62],[-298,243],[-235,33]],[[30948,67736],[-130,-240],[-495,-145],[-80,214],[-344,190],[-466,-311],[93,-129],[-311,-206],[-66,-147],[-379,-41],[-68,-196],[-276,66],[-292,-73],[25,-346]],[[33110,67945],[-269,347],[-228,0],[-139,-121],[-321,12],[-616,-378],[-589,-69]],[[34351,64706],[-338,335],[19,211],[-242,55],[98,289],[-258,201],[-274,46],[-473,284],[68,181],[304,237],[41,214],[-172,516],[-175,55],[195,314],[-34,301]],[[28159,66372],[624,-70],[1281,243],[150,-69],[147,-308],[177,26],[79,-283],[250,3],[11,130],[671,281],[-60,71],[277,96],[287,-249],[88,159],[239,-103],[103,-257],[225,-138],[24,-113],[279,-101],[-75,-48],[100,-292],[138,65],[102,-253],[105,45],[179,-364],[268,-61],[92,-144],[431,68]],[[24938,64086],[-232,-236],[9,-200],[337,-412],[275,-64],[456,382],[216,71]],[[26121,64849],[-93,427],[128,343],[-53,110],[244,326],[-21,180],[236,107],[287,392],[321,139],[-189,184],[-165,315],[72,122],[-534,980],[65,198],[-331,103]],[[25999,63627],[202,429],[-40,258],[-109,89],[93,182],[110,-44],[-134,308]],[[34519,75615],[61,-164],[352,157],[79,-341],[-183,-83],[103,-433],[-89,-311],[7,-399],[-89,147],[-224,-83],[-240,-208],[-231,426],[-102,-367],[220,-384],[-207,-47],[-263,-179],[-355,63],[-236,-44],[-282,38]],[[36294,73414],[-166,-5],[2,131],[-317,425],[-66,588],[-91,187],[101,163],[-53,159],[130,56],[-44,171],[136,139],[-201,533],[-671,-299],[-187,217],[-348,-264]],[[37059,72307],[-619,12],[69,98],[-342,386],[198,185],[46,339],[-117,87]],[[37247,71716],[-157,37],[33,219],[-101,195],[37,140]],[[36598,70618],[-138,165],[-5,173],[545,-106],[83,663],[164,203]],[[36040,69566],[237,71],[-67,218],[323,316],[-34,309],[99,138]],[[35623,69244],[129,174],[204,-57],[84,205]],[[31862,71475],[210,-153],[160,49],[330,-76],[242,-195],[305,-35],[53,-109],[324,-23],[214,65],[-37,-426],[162,-183],[-24,-204],[1619,-525],[-159,-207],[362,-209]],[[33110,67945],[637,163]],[[29842,70661],[-18,-150],[-290,-277],[-140,22],[-439,-614],[58,-301],[368,253],[199,-100],[-135,-393],[251,-162],[188,128],[-24,-241],[352,-477],[478,-322],[258,-291]],[[33747,68108],[-16,212],[211,37],[223,334],[-102,315],[195,121],[654,59],[134,-240],[219,28],[108,167],[210,-125],[40,228]],[[26121,64849],[406,-63],[-34,302],[254,90],[27,224],[-69,517],[173,258],[603,401],[116,-75],[562,-131]],[[56570,88006],[136,138],[414,227],[200,332],[367,450],[72,-121],[202,422]],[[54407,87762],[161,-163],[460,382],[686,-89],[63,124],[125,-86],[396,106],[7,163],[265,-193]],[[54334,88597],[174,-157],[-29,-280],[-97,-237],[25,-161]],[[55933,90447],[62,-289],[-594,-39],[-243,-230],[-107,-498],[-151,-203],[-367,-133],[-199,-458]],[[57415,90900],[-142,-195],[-392,-86],[-316,-9],[-288,-256],[-131,199],[-213,-106]],[[58119,90117],[-141,78],[2,261],[-559,349],[-6,95]],[[57961,89454],[112,329],[46,334]],[[60350,78243],[219,130],[337,7],[207,307],[285,12],[216,101],[81,167]],[[58684,79936],[264,-86],[177,223],[187,-256],[188,145],[138,-103],[163,86],[138,-116],[140,106],[152,-374],[-177,-205],[120,-296],[-10,-519],[186,-298]],[[61447,80737],[-143,-113],[-300,-35],[-63,-228],[-265,-311],[-243,-26],[-30,107],[-402,-75],[-211,19],[-134,236],[-283,25],[-7,-162],[-276,-17],[6,120],[-206,86],[-8,-144],[-198,-283]],[[61695,78967],[38,359],[-118,219],[54,333],[315,492],[-170,236],[-126,-50],[-241,181]],[[55933,90447],[-586,-208],[-209,358]],[[53337,88379],[854,72],[143,146]],[[53185,88492],[152,-113]],[[52817,89048],[-22,-120],[480,-203],[-90,-233]],[[53186,89691],[161,-370],[-530,-273]],[[55138,90597],[-336,-10],[-211,67],[-459,-112],[-560,-522],[46,-102],[-264,-225],[-168,-2]],[[55775,82262],[193,34],[76,620],[306,183],[-18,224],[233,394],[-86,247],[374,254],[2,89]],[[55394,82636],[152,-158],[-156,-119],[91,-122],[294,25]],[[54701,83988],[228,-524],[-279,-173],[152,-261],[360,-25],[232,-369]],[[56406,85644],[-48,-184],[-182,-52],[-370,-406],[-438,-269],[-639,-666],[-28,-79]],[[57519,85599],[-174,174],[-90,-219],[-140,67],[-193,243],[-516,-220]],[[56855,84307],[-156,228],[-217,126],[-250,42],[-37,94],[321,433],[117,-92],[278,74],[608,387]],[[59263,84127],[328,-128],[83,-250],[144,-67],[383,57],[141,83]],[[59806,84673],[-63,-115],[-480,-431]],[[61298,85182],[-533,269],[-273,9],[-58,-134],[-374,-105],[-128,-194],[-126,-354]],[[60342,83822],[376,321],[273,121],[-4,235],[526,112],[25,111],[-431,77],[295,306],[-104,77]],[[61846,81256],[-83,-223],[-179,90],[78,157],[-407,4]],[[63368,82453],[-327,38],[-168,-123],[-458,-165],[150,-270],[-218,-189],[-132,-320],[-217,-18],[-152,-150]],[[63174,78353],[708,355],[79,94],[19,305],[206,36],[-84,235],[130,314],[-32,304],[-169,285],[-255,252],[-200,286],[-172,432],[-115,548],[8,427],[71,227]],[[61695,78967],[407,-151],[163,40],[106,195],[276,82],[86,-372],[241,36],[-94,-224],[294,-220]],[[61255,81284],[99,-503],[93,-44]],[[61298,85182],[281,139],[298,373],[118,-34],[63,212]],[[57519,85599],[-25,280],[403,-103],[132,151],[71,-141],[433,-54],[260,157],[355,-132],[134,-250],[71,-573],[-84,-122],[246,-29],[189,95],[102,-205]],[[56570,88006],[-411,-274],[27,-243],[153,12],[24,-317],[112,-198],[-46,-341],[96,-555],[-295,-163],[176,-283]],[[60945,88059],[-128,-564],[-213,-167],[-231,36],[-144,324],[-216,38],[-104,367],[3,301],[-192,-52],[-24,181],[-495,275],[-267,303],[-437,-193],[-64,226],[-406,102],[-66,218]],[[62058,85872],[-115,365],[-263,429],[-227,603],[14,222],[-200,82],[-2,189],[-320,297]],[[57739,83123],[150,141],[-12,204],[104,92],[126,-111],[89,437],[-10,484],[207,-34],[38,196],[323,-276],[63,66],[446,-195]],[[56855,84307],[141,-58],[216,114],[235,-178],[58,-143],[19,-503],[183,-47],[32,-369]],[[60660,82765],[-72,180],[107,243],[-27,346],[-98,-87],[-46,254],[-182,121]],[[61255,81284],[-136,-28],[-265,108],[168,137],[-180,76],[-201,204],[-129,337],[137,188],[-79,211],[90,248]],[[58025,78909],[23,158],[189,276],[-57,91],[165,232],[344,128],[-5,142]],[[57683,78889],[342,20]],[[55324,79690],[62,-305],[207,-106],[196,148],[222,29],[189,159],[85,197],[-16,250],[131,71],[204,368],[385,278],[206,-106],[138,89],[297,-95],[60,-198],[-111,-234],[-39,-377],[-133,-487],[19,-176],[257,-306]],[[55942,81511],[-112,-95],[10,-229],[-151,-273],[-126,-50],[-3,-349],[-274,-291],[38,-534]],[[57739,83123],[33,-66],[-299,-53],[-244,-271],[74,-274],[-449,-255],[21,-156],[-208,-144],[-72,-194],[-653,-199]],[[63368,82453],[143,365],[247,362],[-165,158],[-92,450],[-149,146],[-62,228],[-405,250],[-285,266],[-109,321],[-114,-30],[-114,180],[82,60],[-85,504],[-202,159]],[[60660,82765],[140,-167],[183,-32],[235,167],[424,-181],[190,29],[-105,-316],[15,-672],[-135,-58],[239,-279]],[[54257,77276],[2,-253],[-174,-393],[-164,-248],[671,162],[355,-51],[76,-162],[-86,-327]],[[54724,77988],[-185,-282],[13,-135],[-295,-295]],[[56215,76791],[-164,21],[9,635],[-311,219],[-184,60],[-171,-86],[-64,245],[-324,7],[-227,-139],[-55,235]],[[54937,76004],[319,-181],[166,137],[389,-83],[218,383],[56,336],[130,195]],[[60256,91031],[-629,-36],[-395,-190],[-353,-302],[-506,-241],[-120,-226],[-134,81]],[[60945,88059],[-90,12],[-32,589],[43,319],[96,202],[-134,246],[-165,74],[-274,544],[-233,347],[-20,175],[145,124],[-129,172],[104,168]],[[58025,78909],[209,-70],[54,-291],[324,-169],[388,-7],[151,92],[221,-103],[369,39],[153,-230],[233,-76]],[[60127,78094],[223,149]],[[59155,75626],[-116,335],[246,237],[196,578],[279,322],[43,446],[130,135],[4,164],[143,60],[47,191]],[[57772,75775],[175,-69],[263,114],[489,129],[40,-348],[160,-55],[256,80]],[[57965,78005],[143,-535],[-102,-109],[49,-165],[-89,-158],[71,-163],[-234,-398],[54,-431],[-85,-271]],[[57683,78889],[50,-378],[327,-188],[-95,-318]],[[55775,82262],[60,-452],[107,-299]],[[55836,91474],[53,-129],[-715,-752],[-36,4]],[[57664,91287],[-102,114],[-545,407],[-77,631],[-608,-119],[-257,-406],[-117,-328],[-122,-112]],[[57415,90900],[71,196],[178,191]],[[54407,87762],[-130,-165],[-4,-242],[-212,-266],[-373,-244],[-39,-195]],[[54200,85071],[139,-343],[362,-740]],[[53649,86650],[74,-394],[188,101],[427,75],[35,-304],[-115,-219],[35,-506],[-93,-332]],[[55324,79690],[-154,-32],[-103,-204],[-203,63],[149,-165],[14,-258],[-342,-347],[-218,-365],[257,-394]],[[56215,76791],[194,99],[175,236],[-40,250],[95,548],[337,4],[220,241],[247,-80],[-52,223],[363,-118],[211,-189]],[[60256,91031],[127,224],[-57,279],[76,39],[-170,554],[-146,102],[-429,-339],[-213,-83],[-482,189],[-106,174],[2,252],[-203,65],[-256,-217],[-262,-452],[-379,-352],[-94,-179]],[[27009,58533],[736,-63],[221,18],[630,270],[281,-8],[134,-150],[34,-448],[236,20]],[[27757,60249],[-139,-199],[-9,-299],[102,-427],[-278,-240],[-164,-56],[-293,-386],[33,-109]],[[31810,62243],[-189,-403],[-543,-427],[-188,-74],[-235,40],[-159,-168],[50,-163],[-284,-42],[-11,129],[-200,-63],[24,-139],[-153,-127],[-825,29],[-220,-302],[-935,-173],[-185,-111]],[[34355,63138],[-241,-116],[-516,48],[-392,-221],[-663,-61],[-162,-81],[-133,-393],[-218,-160],[-220,89]],[[35359,63524],[-428,-221],[-338,-50],[-238,-115]],[[36289,64263],[-109,-149],[173,-172],[155,93],[135,-68],[-18,-263],[-169,-83],[-150,198],[-128,-3],[-104,-227],[-15,-436],[-94,-157],[-195,63],[-47,223],[-179,204],[-185,38]],[[36910,64442],[-46,640],[-96,46],[-190,-200],[-63,-368],[-226,-297]],[[38765,63278],[-275,-11],[-89,-146],[-356,-110],[-71,394],[-118,317],[-787,136],[-64,99],[-95,485]],[[39509,60233],[-187,225],[-42,-71],[-172,195],[-289,134],[41,471],[-448,543],[180,106],[-53,214],[84,186],[-113,218],[458,175],[21,316],[-224,333]],[[38028,58783],[-104,367],[115,56],[277,312],[-42,91],[282,350],[426,-81],[220,21],[82,186],[169,-108],[128,192],[-72,64]],[[29281,58172],[510,42],[-36,478],[578,68],[372,153],[415,39],[-9,136],[306,61],[200,130],[-26,182],[428,30],[-1,-125],[381,88],[-59,-239],[144,-257],[330,311],[361,-396],[172,-103],[338,-410],[41,295],[372,140],[-62,467],[424,116],[54,515],[187,-46],[221,-215],[237,47],[460,-328],[333,-55],[-241,234],[102,181],[238,-80],[538,-355],[68,134],[505,280],[228,-78],[115,-276],[523,-553]],[[42747,64290],[-268,-14],[-261,-371],[-220,19],[-306,-68],[153,297],[62,264],[-61,602],[171,340],[209,534],[-461,101],[372,153],[-31,256]],[[42344,62493],[401,-90],[66,282],[-79,549],[194,347],[53,427],[-81,82],[75,251],[-226,-51]],[[40365,62757],[-19,208],[158,171],[303,-575],[70,150],[-68,228],[110,68],[182,-110],[160,-526],[344,110],[79,-203],[163,-41],[196,317],[161,40],[140,-101]],[[39172,63189],[170,-249],[161,77],[72,-299],[186,156],[109,-113],[276,245],[219,-249]],[[38380,65905],[46,-245],[-96,-297],[206,-308],[183,-58],[-103,-250],[40,-106],[269,-166],[9,-227],[201,132],[215,-405],[-73,-273],[-139,-210],[129,-193],[-95,-110]],[[40494,66057],[-184,40],[-433,-321],[-115,385],[-104,124],[-328,88],[-159,-255],[-315,-141],[-476,-72]],[[41463,66488],[-148,27],[-398,-91],[-174,-213],[-249,-154]],[[42106,66403],[-207,-149],[-363,65],[-73,169]],[[35835,64694],[-80,-212],[-508,-217],[-89,-141],[-96,-563],[297,-37]],[[36289,64263],[-144,276],[123,351],[-263,24],[-170,-220]],[[35835,64694],[62,455],[-96,327],[-175,343],[180,73],[-123,332],[285,136],[-48,82],[276,99],[-121,315]],[[34351,64706],[219,-324],[-29,-191],[-446,-140],[31,-501],[229,-412]],[[36075,66856],[-47,229],[-241,27],[-249,133],[-224,33],[-75,171],[-282,58],[-382,298],[-24,-97],[-252,-22],[-450,60],[-102,362]],[[38059,58738],[-31,45]],[[36779,56766],[-111,179],[260,116],[-203,114],[68,160],[546,-187],[125,113],[-200,346],[503,584],[-145,211],[246,110],[191,226]],[[35953,54310],[-80,316],[74,159],[-313,-120],[-138,148],[215,295],[358,367],[115,-11],[343,178],[276,619],[-24,505]],[[32420,52369],[194,132],[-108,325],[288,210],[-115,142],[-135,562],[355,115],[95,194],[-130,66],[-53,447],[309,8],[221,93],[489,-45],[41,-129],[352,-51],[70,-162],[164,-70],[156,103],[92,-230],[137,-107],[227,30],[536,-304],[241,306],[-65,130],[170,-6],[2,182]],[[31032,52660],[173,169],[290,-5],[210,-263],[153,-50],[95,105],[186,-194],[129,95],[152,-148]],[[30672,54894],[-69,-947],[92,-483],[284,-246],[-28,-360],[81,-198]],[[29281,58172],[30,-410],[230,-379],[67,67],[53,-284],[-45,-306],[140,-111],[70,-211],[166,19],[130,-329],[314,-225],[157,-724],[179,-274],[-100,-111]],[[41259,60043],[-97,366],[-177,145],[-320,100],[2,223]],[[41240,58785],[-3,467],[87,-5],[90,397],[-200,167],[45,232]],[[40110,57824],[-24,194],[95,170],[173,28],[199,191],[-174,221],[513,398],[282,-254],[66,13]],[[39030,58710],[880,-576],[200,-310]],[[38059,58738],[174,-185],[169,26],[377,225],[251,-94]],[[40497,61273],[-35,-254],[-127,-14],[-14,-170],[-508,-461],[-221,114],[-83,-255]],[[40667,60877],[-9,337],[-161,59]],[[32987,51627],[450,-258],[183,-51],[447,-264],[63,67],[368,-111],[347,447],[440,289],[112,2]],[[32420,52369],[177,-53],[115,-443],[275,-246]],[[35471,51800],[175,332],[-55,118],[124,134],[-155,37],[18,188],[257,-16],[295,515],[-251,242],[14,229],[208,444],[162,82],[-310,205]],[[35397,51748],[74,52]],[[40365,62757],[0,-124],[288,-250],[-48,-184],[84,-212],[-192,-714]],[[40667,60877],[448,48],[99,-176],[-18,-227],[170,-69],[-79,366],[246,50],[-8,289],[213,-212],[88,240],[365,248],[-133,158],[-32,198],[99,41],[19,284],[-102,69],[-26,220],[292,-26],[36,115]],[[41259,60043],[258,-9],[-17,-91],[275,-2],[648,-209],[240,170],[-22,212],[123,378],[182,73],[6,172],[232,-241],[266,24],[43,-299],[451,-56],[583,104],[-235,446],[323,214],[240,40],[314,-119],[194,236],[285,237],[463,12],[-64,-112]],[[44563,65304],[-27,-114],[-310,-188],[-160,-226],[-277,-69],[-316,189],[28,632],[-204,-24],[-9,185],[-235,-15],[49,-196],[-45,-305],[-142,-363],[-218,-409],[50,-111]],[[45598,64567],[-216,-52],[-285,96],[-101,175],[-166,-84],[-238,245],[-29,357]],[[46278,63844],[19,272],[-216,-100],[-348,342],[-135,209]],[[46047,61223],[211,59],[343,213],[93,304],[-374,373],[357,231],[218,-8],[-83,253],[307,98],[-89,485],[-234,91],[-14,141],[237,154],[241,49],[-16,82],[-322,-133],[-355,63],[-289,166]],[[27724,62555],[705,308],[562,-327],[485,-15],[817,-171],[410,334],[894,146],[124,-452],[89,-135]],[[25999,63627],[303,-126],[145,-255],[-58,-464],[255,-20],[232,389],[218,-3],[322,-520],[308,-73]],[[38185,65978],[-121,197],[-172,98],[-11,-132],[-639,31],[-626,216],[-238,602],[-225,-181],[-78,47]],[[36910,64442],[422,-170],[251,168],[102,378],[193,38],[170,287],[-114,147],[291,408],[-40,280]],[[38765,63278],[407,-89]],[[38380,65905],[-195,73]],[[26336,79903],[-51,189],[273,10],[40,222],[-156,144],[516,132],[409,467]],[[24508,78104],[91,155],[182,-27],[233,109],[63,178],[251,153],[-57,143],[263,250],[-150,114],[-121,336],[513,263],[82,-175],[496,137],[-18,163]],[[24396,78214],[112,-110]],[[23389,78904],[245,-54],[93,-173],[247,184],[133,-205],[286,-174],[3,-268]],[[22078,78602],[502,453],[360,190],[271,-163],[-167,-216],[297,137],[48,-99]],[[21183,79169],[365,-381],[321,-148],[101,84],[108,-122]],[[22834,81217],[526,54],[557,274],[281,-92],[-18,-125],[-255,-334],[-196,-162],[-95,-269],[-263,-42],[-52,-144],[-218,-140],[-140,95],[-446,-266],[-132,-139],[-444,-229],[-72,59],[-423,-373],[-166,-230],[-95,15]],[[24452,82599],[-111,-166],[-273,-71],[-380,-306],[-174,-44],[-63,-215],[-162,-87],[-114,-204],[-341,-289]],[[26945,83096],[-18,388],[-457,-236],[-693,-289],[-175,-42],[-81,-293],[-209,9],[-129,-95],[-278,84],[-119,-135],[-75,92],[-259,20]],[[28053,82216],[-180,11],[-277,-117],[-67,168],[-113,-111],[-133,183],[-105,-30],[14,225],[-247,551]],[[27367,81067],[-122,380],[57,135],[321,67],[535,225],[-105,342]],[[20544,79590],[603,-348]],[[22834,81217],[-188,-41],[-641,-622],[-168,-308],[-763,-154],[-530,-502]],[[21147,79242],[36,-73]],[[37013,81442],[23,175],[-312,735],[-277,536],[-34,300],[-106,108],[60,198],[-194,-33],[40,229]],[[36097,80869],[489,450],[427,123]],[[34241,82013],[185,-383],[188,166],[230,-414],[533,106],[153,-189],[220,-37],[271,-243],[76,-150]],[[36213,83690],[-118,138],[-90,364],[-153,93],[-171,-56],[-148,-223],[42,-628],[-94,-145],[-251,-157],[-478,-179],[-107,-205],[-46,-362],[-157,-216],[-201,-101]],[[28743,77189],[-420,-270]],[[29431,77613],[-133,-50],[-555,-374]],[[30347,77320],[-139,-125],[-208,258],[-91,-248],[-162,-35],[-316,443]],[[30349,75316],[115,359],[-60,157],[113,73],[-171,214],[96,58],[-45,376],[205,50],[-209,504],[-46,213]],[[32513,81947],[-325,11]],[[33175,81838],[-66,73],[-489,-96],[-107,132]],[[33729,80002],[-164,-7],[-164,122],[-130,-100],[-172,156],[-63,209],[-328,278],[214,816],[253,362]],[[32774,78455],[199,165],[-30,268],[497,297],[-32,143],[140,219],[273,85],[70,294],[-162,76]],[[31816,78126],[162,-71],[96,148],[212,76],[120,-134],[176,58],[192,252]],[[31574,78202],[129,62],[113,-138]],[[30195,79795],[70,254],[218,-10],[-29,283],[335,20],[169,-326],[148,-479],[-210,-168],[79,-179],[-253,-318],[-166,-75],[64,-339],[233,-360],[272,149],[31,-71],[283,329],[135,-303]],[[29513,80091],[682,-296]],[[29966,81009],[-247,-216],[-231,-582],[25,-120]],[[32188,81958],[73,-238],[-423,-347],[-298,214],[-358,151],[-346,-8],[-259,-89],[-9,-137],[338,-342],[-82,-165],[-459,79],[-399,-67]],[[31574,78202],[-276,-233],[56,-272],[-421,-124],[-12,-182],[-182,-5],[-272,127],[-120,-193]],[[32478,75495],[37,95],[-80,436],[-134,294],[3,203],[-209,212],[-141,441],[-245,304],[142,136],[-92,353],[57,157]],[[31540,74897],[547,67],[-97,179],[27,204],[192,216],[269,-68]],[[30195,79795],[187,-323],[-117,-308],[-215,-209]],[[30050,78955],[-170,-152],[317,-81],[-113,-214],[-228,-2],[-211,-216],[-162,35],[-143,-170],[-87,-314],[178,-228]],[[30985,82918],[255,-88],[206,44],[22,-455],[114,72],[498,-344],[108,-189]],[[30595,84587],[316,-496],[196,-650],[-242,-201],[128,-170],[-8,-152]],[[30165,86440],[-413,-364],[9,-432],[66,-425],[161,-321],[190,-35],[417,-276]],[[32513,81947],[-22,359],[156,96],[385,-52],[67,69],[-138,403],[-385,974],[-248,471],[-274,341],[-433,216],[-170,362],[-162,-99],[-523,-187],[-476,1541],[-125,-1]],[[37013,81442],[261,-140],[70,-153],[193,34],[288,-237],[686,312],[213,364],[402,246],[262,256],[-156,245],[427,424],[-85,136],[-162,-33],[-423,189],[-358,-136],[-151,440],[-202,393],[-253,122],[258,161],[-149,245],[248,250],[-54,251],[-571,-53],[-675,-126],[-432,55],[-25,-148],[95,-383],[-144,-284],[-363,-182]],[[30031,78978],[19,-23]],[[29482,79785],[257,-43],[109,-102],[-9,-320],[192,-342]],[[29513,80091],[-31,-306]],[[29084,82259],[652,-1016],[230,-234]],[[30985,82918],[6,-325],[-808,-38],[-292,-77],[-121,60],[-131,-208],[-152,26],[-403,-97]],[[35265,79946],[-334,509],[-409,-274],[-221,23],[4,274],[-372,-110],[22,-189],[-226,-177]],[[32774,78455],[137,-244],[64,-382],[314,213],[547,-394],[157,41],[205,208],[640,158],[36,-67],[271,84],[270,232],[356,-50],[165,-112],[140,181],[-397,158],[-25,139],[147,-8],[71,201],[-59,169],[-262,-214],[-94,250],[-203,-30],[-169,358],[-122,86],[305,257],[-3,257]],[[27548,83703],[-1,-203],[-409,-183],[-193,-221]],[[30595,84587],[-87,-295],[-604,-353],[-345,-102],[-385,225],[-277,-42],[-690,-178],[-350,-10],[-309,-129]],[[28053,82216],[526,147],[505,-104]],[[35265,79946],[244,173],[248,87],[319,24],[96,186],[-75,453]],[[34241,82013],[-579,69],[-487,-244]],[[34519,75615],[-368,-214],[-587,-91],[-585,-153],[-38,278],[-193,102],[-270,-42]],[[42174,76893],[-167,-10],[118,-163],[-62,-137]],[[43778,75514],[-673,420],[-356,282],[-575,677]],[[43205,74610],[441,503],[132,401]],[[42063,76583],[124,-289],[443,-355],[-194,-244],[127,-172],[-21,-210],[80,-219],[383,-396],[200,-88]],[[49595,76830],[-237,211],[76,372],[246,284],[353,221],[307,317],[167,96],[-2,190]],[[48516,77162],[477,-114],[602,-218]],[[47290,78264],[-13,-184],[181,-138],[416,-71],[135,-115],[172,176],[80,-221],[161,-93],[141,-286],[-47,-170]],[[47618,79209],[-54,-217],[-139,-25],[-148,-312],[169,-137],[-156,-254]],[[48862,79562],[-106,-299],[-244,-64],[-410,239],[-139,-27],[-128,-181],[-217,-21]],[[49196,79480],[-334,82]],[[50505,78521],[-116,163],[-250,87],[-338,232],[-215,66],[-323,-83],[-167,215],[100,279]],[[42365,68342],[-188,-97],[-396,619]],[[42159,66475],[171,86],[-8,166],[191,229],[37,616],[-99,659],[-86,111]],[[41781,68864],[-265,-218],[-209,-298],[-338,-181],[54,-122],[-159,-49],[137,-274],[306,-273],[52,-113],[276,97],[293,6],[61,-313],[-51,-201],[87,-377],[134,-73]],[[45025,70783],[-14,-19]],[[45982,71501],[231,-26],[-43,-107],[177,-244],[-384,-539],[-293,-276],[-196,-50],[-449,524]],[[45508,71647],[218,-63],[310,28],[-54,-111]],[[46277,73023],[-189,-96],[-232,-687],[-147,-270],[-157,-64],[-44,-259]],[[48305,74523],[-7,-278],[121,-281],[-35,-148],[-210,-90],[1,-146],[-186,39],[241,-440],[-118,-234],[-314,-407],[-147,154],[-92,-185],[-1006,620],[-131,111],[-145,-215]],[[48865,74238],[-53,-37],[-507,322]],[[48819,69027],[-164,389],[-132,100],[89,198],[321,379],[-271,157],[94,293],[-64,117],[164,223],[-55,136],[90,191],[-214,199],[182,268],[6,204],[245,488],[334,371],[37,183],[-213,-114],[-306,452],[-140,-178],[-95,37],[54,254],[113,44],[-135,173],[63,242],[170,166],[6,161],[-133,78]],[[48618,68852],[201,175]],[[44798,69019],[293,0],[48,180],[370,127],[387,234],[169,-64],[202,66],[44,479],[-56,121],[161,63],[128,-79],[348,26],[233,291],[215,-205],[182,40],[48,-134],[247,-165],[641,-1119],[160,-28]],[[44817,69473],[-10,-193],[-139,-99],[130,-162]],[[45011,70764],[-269,-223],[12,-262],[114,-365],[-191,-268],[140,-173]],[[44580,76419],[1,-327],[421,-457],[-90,-115],[416,-304],[-31,-269],[252,-158],[208,-333],[636,136],[501,-20],[-82,165],[344,-196],[426,-64],[678,352],[-143,409],[184,527],[189,23]],[[45418,78197],[54,-305],[-51,-188],[284,-144],[2,-170],[-241,-322],[-289,176],[-161,-133],[51,395],[-115,61],[-195,-743],[-112,16],[-65,-421]],[[47290,78264],[-300,65],[-85,-138],[-288,195],[-44,-97],[-255,35],[10,-152],[-357,-82],[-553,107]],[[48490,75788],[70,236],[-112,184],[-382,126],[-108,95],[124,361],[-95,65],[225,231],[259,-76],[45,152]],[[45716,64954],[-158,-210],[40,-177]],[[46598,65886],[-210,-130],[-38,-213],[491,-143],[-205,-330],[-421,-132],[-499,16]],[[48618,68852],[-377,-325],[201,-433],[-85,-126],[-171,105],[-118,-129],[-104,80],[-337,-143],[-232,-270],[-131,-456],[224,-231],[-34,-246],[-253,-33],[-352,-193],[-251,-566]],[[48986,68781],[-167,246]],[[50050,67380],[-268,189],[-207,297],[-404,300],[-110,136],[-75,479]],[[51373,65122],[-192,158],[-4,268],[76,68],[-139,452],[-59,390],[207,93],[-301,231],[-35,165],[-436,144],[-440,289]],[[51469,64373],[108,417],[133,126],[-337,206]],[[49714,64259],[88,196],[153,5],[3,167],[331,-68],[-187,-117],[-33,-224],[297,-130],[172,248],[396,-21],[-71,-146],[155,-130],[242,263],[209,71]],[[46278,63844],[311,205],[463,205],[92,-100],[663,603],[146,26],[121,-276],[181,-170],[343,62],[158,-139],[134,28],[245,259],[157,-345],[155,173],[267,-116]],[[48986,68781],[321,11],[271,148],[11,240],[244,248],[188,20],[392,333],[225,-1],[108,111],[219,-140],[152,149],[-182,136],[337,246],[-302,297],[375,573],[154,-83],[404,-67],[117,135],[119,478],[288,437],[130,340],[311,263]],[[52009,73461],[-133,140],[-7,187],[124,212],[-21,177],[-332,13],[-273,-162],[-105,168],[10,273],[-210,301],[-423,153],[-118,122],[-361,108],[-629,-121],[-192,-271],[-17,-192],[-330,-166],[-127,-165]],[[52868,72655],[70,365],[-422,257],[-112,-81],[-118,138],[-277,127]],[[53034,73689],[576,107],[230,381]],[[53840,74177],[-18,143],[-251,646],[-158,133],[-246,-197],[-144,-260],[12,-471],[-82,-215],[81,-267]],[[49196,79480],[348,279],[-32,163],[-156,112],[9,221],[257,93],[140,165],[-269,393],[-123,81]],[[48898,80737],[-329,-253],[55,-179],[-51,-210],[92,-363],[197,-170]],[[49370,80987],[-126,-168],[-346,-82]],[[41403,69747],[58,-191],[-54,-188],[222,0],[-45,-182],[197,-322]],[[42168,71509],[-164,-171],[-306,-157],[189,-240],[-179,-296],[-305,-898]],[[43148,71699],[-73,140],[-251,-105],[-537,-367],[-119,142]],[[44301,71520],[-339,-88],[-49,101],[-202,-96],[-46,145],[-269,-12],[-248,129]],[[45011,70764],[-81,352],[160,64],[-379,-4],[-115,-185],[-119,346],[-176,183]],[[42365,68342],[159,188],[-181,256],[186,448],[162,-51],[223,164],[82,247],[131,-113],[44,140],[208,-217],[46,194],[176,-115],[324,158],[19,281],[292,214],[90,-99],[-77,-220],[85,-137],[-90,-159],[324,-114],[249,66]],[[48898,80737],[-266,247],[-52,203],[-271,-145],[-48,119],[-214,51],[-145,-142],[-445,65]],[[47609,80026],[111,-146],[-16,-402],[-130,-89],[44,-180]],[[47457,81135],[159,-115],[-7,-994]],[[43948,73035],[-397,164],[-111,237],[-390,463],[-158,-100],[6,-450],[-396,-67],[-26,-243],[-209,-291],[-141,-681]],[[43148,71699],[796,1140],[4,196]],[[42126,72067],[223,-246],[-181,-312]],[[43778,75514],[455,-332],[628,-643],[290,-415]],[[44580,76419],[-177,72],[-60,-198],[-221,-49],[130,-194],[-531,-253],[57,-283]],[[48664,75442],[-174,346]],[[48305,74523],[-18,533],[377,386]],[[45151,74124],[306,-459],[341,-375],[479,-267]],[[45200,80589],[-7,-76],[242,-373],[-203,-679],[-149,-643],[196,-8],[14,-293],[100,-23],[25,-297]],[[45222,80588],[-22,1]],[[46389,81094],[-434,-106],[-340,105],[-255,-176],[-138,-329]],[[47609,80026],[-396,95],[-88,-101],[87,-416],[-545,-44],[129,268],[-164,132],[26,118],[-245,-32],[169,149],[-161,114],[71,102],[-90,330],[-13,353]],[[42159,66475],[-53,-72]],[[46070,66784],[-44,357],[-196,64],[105,288],[154,138],[-27,166],[-283,21],[-308,140],[-404,-105],[-97,93],[-1,258],[178,27],[60,168],[-273,520],[-136,100]],[[45058,65939],[168,204],[383,159],[190,199],[-68,124],[339,159]],[[44563,65304],[163,262],[219,75],[113,298]],[[44301,71520],[-96,160],[383,116],[-43,195],[128,113],[328,-169],[-44,-186],[132,-167],[419,65]],[[44053,73261],[-105,-226]],[[45151,74124],[-288,-128],[-97,-150],[-118,82],[-207,-314],[-164,70],[-224,-423]],[[46070,66784],[133,-301],[10,-223],[385,-374]],[[45716,64954],[-8,180],[-340,117],[-99,217],[77,113],[-288,358]],[[45982,71501],[-63,-107],[-224,53],[-172,-242],[-224,-104],[50,-72],[-324,-246]],[[43205,74610],[610,-620],[94,-170],[-39,-263],[183,-296]],[[48664,75442],[183,275],[369,136],[320,-21],[83,621],[130,44],[-84,360],[-70,-27]],[[47457,81135],[-402,344],[-61,-201],[-418,-166],[-187,-18]],[[54222,77259],[-66,-110],[-368,17],[-215,236],[-220,494],[-180,133],[-152,376],[-84,379],[-281,131],[-116,131],[-39,335],[-682,-139],[-263,-131],[-174,-405],[-429,-87],[-109,92],[-111,-166],[-228,-24]],[[54257,77276],[-35,-17]],[[54538,74667],[85,72],[9,506],[-173,144],[42,107],[296,202],[-28,123],[168,183]],[[53840,74177],[328,-105],[292,349],[78,246]],[[52009,73461],[25,204],[393,521],[44,-206],[159,-107],[122,-228],[282,44]],[[17685,81661],[1327,779]],[[17340,81494],[345,167]],[[14734,86510],[84,-286],[238,-149],[316,-58],[213,-162],[294,94],[219,-312],[81,-762],[40,-58],[22,-573],[437,-154],[-86,-522],[166,1],[-30,-575],[254,-315],[161,-316],[-169,-116],[157,-265],[209,-488]],[[14836,86843],[-102,-333]],[[17422,87485],[-367,-132],[-71,121],[-187,-163],[-291,-55],[-285,-203],[-374,-191],[-276,-7],[-2,-122],[-544,44],[-189,66]],[[18251,87285],[-257,140],[-572,60]],[[19012,82440],[-328,997],[-266,1401],[-53,575],[140,817],[-71,749],[-183,306]],[[13364,79646],[-207,856],[-227,559],[-360,794],[-157,559],[10,635],[-127,808],[-61,75],[-726,157],[-353,321],[-532,737],[-364,442]],[[11979,79109],[570,171],[815,366]],[[9664,85291],[-82,-353],[95,-624],[214,-366],[246,-171],[199,-391],[134,-380],[316,-503],[471,-1016],[144,-736],[268,-726],[310,-916]],[[10260,85589],[-139,-208],[-457,-90]],[[15021,80351],[1046,568],[107,104],[1166,471]],[[14096,86232],[-53,-257],[338,-1173],[22,-269],[205,-423],[4,-435],[53,-154],[345,-498],[269,-264],[-466,-500],[136,-104],[-236,-262],[296,-539],[-510,-203],[86,-189],[185,-153],[251,-458]],[[14734,86510],[-287,72],[-351,-350]],[[10844,86762],[-293,-738],[-291,-435]],[[14096,86232],[-328,-110],[-156,65],[-324,-33],[-671,-248],[-3,178],[-546,-42],[-111,-180],[-206,98],[-515,-228],[-42,293],[-172,96],[-100,479],[-78,162]],[[13364,79646],[1139,470],[518,235]],[[4508,79527],[-169,163],[-203,570],[-205,331],[-32,291],[-503,1367]],[[1523,78382],[454,-102],[484,-208],[324,161],[378,50],[165,212],[301,243],[483,260],[245,390],[151,139]],[[3396,82249],[-129,-66],[-489,-540],[-645,-284],[-213,-38],[-298,-233],[-245,-96],[-76,270],[-177,111],[19,412],[-186,237],[-298,1303],[-543,-553],[-116,-275],[601,-1223],[57,-190],[489,-933],[71,-221],[464,-833],[-159,-715]],[[11433,87941],[-469,-827],[-120,-352]],[[14836,86843],[-253,37],[-288,-66],[-154,86],[-37,-118],[-185,53],[-190,-168],[-626,-212],[-315,427],[-349,-183],[-85,169],[-142,-51],[-139,227],[-245,-163],[-134,42],[-108,199],[176,236],[-247,372],[-82,211]],[[17977,89702],[-26,-241],[-577,-127],[52,-261],[482,111]],[[18242,89391],[-265,311]],[[17908,89184],[-12,55],[346,152]],[[21260,83145],[-76,-131],[-474,-82],[-395,38],[-208,104],[-284,-66],[-216,-229],[-595,-339]],[[24393,82792],[-629,7],[-613,237],[-207,260],[-265,78],[-250,-10],[-291,-204],[-247,61],[-377,-13],[-254,-63]],[[24452,82599],[-59,193]],[[18212,80422],[353,-544],[571,-731],[105,-227],[1303,670]],[[17685,81661],[527,-1239]],[[4823,76974],[-177,353],[70,180],[-248,300],[3,142],[192,147],[-327,426],[697,582],[-156,219],[-246,-76],[-123,280]],[[1523,78382],[-343,-1513],[-579,-539],[-220,-1036],[-100,-703],[1206,666],[591,438],[829,497],[439,208],[682,522],[205,337],[404,-382],[186,97]],[[29083,87268],[-511,-31]],[[29891,87458],[-347,-108],[-230,48],[-231,-130]],[[30165,86440],[-177,510],[-97,508]],[[28639,86578],[-31,-387],[-356,-21],[89,-353],[118,-40],[184,-336],[139,-589],[-207,-33],[-50,-403],[335,48],[25,-217],[-547,-90],[-659,-166],[-131,-288]],[[28572,87237],[75,-276],[-8,-383]],[[11011,78576],[-381,291],[-1086,1277],[-126,542],[0,298],[-147,310],[91,263],[-50,281],[44,226],[-285,464],[-213,421],[-165,85],[-342,-237],[-144,183],[-288,196],[-230,301]],[[7654,77639],[831,261],[245,272],[274,69],[102,129],[178,-100],[329,73],[607,11],[185,272],[159,38],[447,-88]],[[4931,83906],[192,-101],[98,-204],[542,-586],[296,-452],[843,-1532],[313,-487],[292,-339],[152,21],[132,-295],[-20,-322],[-165,-911],[-25,-525],[73,-534]],[[7689,83477],[-241,-183],[-234,65],[-402,631],[-631,74],[-268,-135],[-171,208],[129,110],[-173,179],[-28,162],[-671,-272],[-68,-410]],[[21597,85891],[-286,189],[-264,84],[-531,336],[-293,224],[-361,197],[-361,125],[-241,11],[-325,200],[-372,70],[-312,-42]],[[21260,83145],[-45,291],[65,377],[-244,919],[181,19],[-90,549],[295,79],[174,181],[1,331]],[[4931,83906],[-139,-509],[-522,-566],[-874,-582]],[[4823,76974],[37,-57],[463,267],[815,194],[580,61],[275,88],[661,112]],[[17977,89702],[124,419],[-42,197]],[[17422,87485],[72,498],[286,506],[201,64],[-73,631]],[[18059,90318],[-416,-177],[-223,-37],[-29,-98],[-618,178],[-509,-60],[-635,-237],[-506,121],[-154,-83],[-280,-357],[-13,-154],[-487,1],[-166,291],[193,156],[-225,375],[-208,-192],[-140,0],[-3,427],[-685,-358],[-545,-122],[-162,-173],[-60,-316],[145,-651],[-214,-179],[-493,-223],[-231,-395],[38,-114]],[[9664,85291],[-434,-87],[-796,-46],[-120,-541],[-301,-472],[-66,-264],[-258,-404]],[[11118,78400],[861,709]],[[11011,78576],[107,-176]],[[28639,86578],[-83,-115],[-384,-20],[-1251,-365],[-177,-142],[-531,-238],[-135,-182],[100,-85],[-155,-242],[-348,-140],[-223,3],[-884,-519],[-118,-241],[98,-316],[-135,-449],[64,-224],[132,-79],[-83,-430],[-133,-2]],[[22826,86515],[-613,-3],[-201,-161],[-415,-460]],[[24295,86944],[-294,-54],[-366,30],[-501,-375],[-308,-30]],[[27127,87453],[-120,-2],[-63,-195],[-589,-219],[-236,11],[-314,-109],[-240,58],[-575,15],[-312,-185],[-116,113],[-267,4]],[[28572,87237],[-1216,130],[-229,86]],[[17790,66846],[37,195],[190,294],[378,419],[64,155]],[[17094,66860],[228,-60],[468,46]],[[17208,68966],[75,-318],[153,-121],[-249,-142],[-556,-48],[-338,-198],[161,-93],[-35,-182],[280,-320],[153,96],[65,-235],[108,112],[167,-319],[-160,-79],[62,-259]],[[17212,68968],[-4,-2]],[[19474,69346],[-199,241],[246,223],[-259,351],[-159,-59],[-225,172],[-118,-102],[-682,-802],[-696,-366],[-170,-36]],[[18459,67909],[34,179],[259,273],[418,353],[-26,82],[340,168],[-182,219],[172,163]],[[13950,69455],[162,32],[282,-330],[-136,-158],[216,-234],[-5,-119],[-573,-663],[179,-192]],[[14141,70698],[40,-217],[-209,-11],[6,-168],[201,3],[86,-170],[-299,-459],[-105,50],[-48,-176],[137,-95]],[[16053,71792],[-485,-515],[-658,-492],[-152,151],[-81,-178],[-536,-60]],[[16238,71505],[-185,287]],[[15213,69995],[-258,482],[37,213],[459,266],[346,317],[97,-9],[344,241]],[[14542,68385],[234,314],[-101,154],[108,122],[-132,119],[262,279],[-48,110],[260,219],[-104,88],[192,205]],[[14075,67791],[163,289],[304,305]],[[13298,69183],[-177,104],[-412,-105],[-444,-412]],[[12265,68770],[91,-57],[-85,-179],[119,-165],[430,380],[177,12],[314,161],[-13,261]],[[19876,69727],[-402,-381]],[[20818,67646],[-152,206],[93,84],[-457,487],[-74,-81],[-273,620],[-88,578],[9,187]],[[18459,67909],[111,-47],[403,315],[435,-362],[219,-334],[-62,-110],[216,-329]],[[11790,68261],[209,96],[266,413]],[[10666,68171],[223,-9],[345,-199],[132,158],[209,-89],[39,142],[176,87]],[[14141,70698],[-319,-68],[-244,107],[-184,351],[101,131],[-388,-238],[-457,-418],[-694,-140],[-179,-85],[-791,-665],[-318,-529],[-25,-381],[23,-592]],[[13298,69183],[358,54],[294,218]],[[13758,67431],[-215,95],[-313,416],[-152,286],[-397,-262],[-255,-23],[-636,318]],[[11085,64178],[670,580],[1430,922],[-115,95],[566,243],[-162,196],[236,181],[-316,154],[-61,99],[207,152],[202,296],[16,335]],[[10666,68171],[-17,-445],[-148,-482],[-368,-480],[585,-368],[335,-260],[69,-253],[371,-521],[199,-508],[-197,-207],[-366,-142],[-116,-181],[72,-146]],[[17208,68966],[-525,-68],[-224,-148],[-73,125],[-344,-224],[-225,286],[-256,-348],[-204,-63],[-219,-328],[-154,230],[-282,-266],[-160,223]],[[17195,64516],[-95,485],[-220,8],[-63,624],[-130,45],[-148,652],[267,-149],[167,124],[-49,278],[185,35],[-15,242]],[[11085,64178],[697,-220],[382,-71],[2162,-84],[2869,713]],[[14075,67791],[-317,-360]],[[19876,69727],[-63,436],[249,299]],[[17322,70396],[100,-164],[197,243],[121,-541],[-83,-100],[-199,38],[-337,-222],[167,-381],[-400,-47],[324,-254]],[[19533,72072],[-103,-332],[-222,-298],[-410,-407],[-562,-257],[-288,72],[-626,-454]],[[20062,70462],[173,308],[-143,351],[-214,98],[142,247],[-153,-18],[-114,424],[-220,200]],[[19266,65279],[-360,470],[-237,-236],[-402,635],[-433,591],[-44,107]],[[17195,64516],[680,170],[327,119],[121,-46],[943,520]],[[21308,70657],[-3,-45],[-1192,-336],[-51,186]],[[22033,69911],[-395,-33],[-94,230],[37,233],[-193,-3],[54,287],[-134,32]],[[19266,65279],[471,260]],[[17322,70396],[-530,-273],[-423,-102],[-303,-150],[-297,-50],[-373,50],[-183,124]],[[43198,82259],[212,92],[109,251]],[[42649,80859],[-117,652],[100,228],[242,139],[324,381]],[[42174,76893],[-177,258],[-44,206],[121,527],[346,531],[208,463],[30,200],[-9,1781]],[[40132,78140],[293,-580],[324,-204],[217,-46],[112,352],[164,-62],[126,396],[248,1],[-76,-455],[202,-294],[24,-484],[163,64],[52,-256],[82,11]],[[43519,82602],[-183,-194],[-369,-245],[-75,-148],[-281,-173],[-229,321],[-339,-115],[-46,167],[-194,-116],[-351,-78],[18,-112],[-343,-127],[235,-606],[330,-282],[10,-194],[-281,-119],[-119,-189],[-42,-325],[-223,-188],[-203,-356],[-128,-339],[-3,-334],[-254,-435],[-317,-275]],[[37689,70053],[-236,-3],[-508,262],[36,410],[-182,-127],[-201,23]],[[37784,69731],[-175,166],[80,156]],[[37334,69008],[42,243],[148,-72],[12,173],[248,379]],[[36040,69566],[255,-109],[-40,-166],[1079,-283]],[[39743,72743],[296,6],[661,-330],[266,-254],[530,-162],[142,137],[191,-216],[297,143]],[[37831,73537],[98,-109],[533,-78],[252,108],[138,208],[328,156],[-89,-354],[16,-310],[333,-86],[303,-329]],[[37736,73808],[95,-271]],[[40132,78140],[-382,-132],[-382,-418],[-1936,-870],[92,-448],[-62,-26],[218,-400],[-66,-28],[412,-842],[167,-95],[99,-237],[-252,-319],[-165,-397],[-139,-120]],[[40319,69743],[125,212],[284,-260],[98,164],[172,-131],[269,133],[136,-114]],[[38729,69760],[292,204],[163,-187],[201,-61],[99,180],[392,-162],[219,-14],[77,129],[147,-106]],[[37784,69731],[60,36],[371,-244],[148,218],[366,19]],[[38970,71402],[13,-289],[-157,-253],[2,-356],[-164,46],[-270,-203],[-55,257],[-420,-96],[-170,23],[-60,-478]],[[39743,72743],[29,-54],[-425,-176],[-81,-256],[96,-55],[-82,-608],[-164,52],[-146,-244]],[[37059,72307],[219,36],[247,262],[-79,209],[123,251],[246,204],[-80,183],[96,85]],[[37736,73808],[-107,38],[-402,-134],[-223,-262],[-29,103],[-509,-156],[-172,17]],[[37247,71716],[144,-27],[556,139],[1,-158],[275,69],[10,-304],[338,6],[190,143],[209,-182]],[[40319,69743],[-167,-716],[419,-10],[-114,-270],[116,-82],[-129,-199],[238,-479],[126,-371],[225,-58],[233,-661],[197,-409]],[[37812,68452],[45,-115],[-124,-564],[-233,20],[-79,-332],[172,-58],[82,-175],[194,-50],[101,96],[159,-100],[-118,-160],[35,-420],[194,-40],[140,-649]],[[37957,68635],[-145,-183]],[[40494,66057],[-40,84],[-5,527],[-308,381],[-53,187],[-89,-75],[-285,442],[-230,242],[-66,321],[-169,-119],[-244,-19],[-1048,607]],[[37812,68452],[-196,73],[126,298],[-410,129],[2,56]],[[38729,69760],[71,-258],[-387,-239],[124,-296],[-157,-118],[115,-91],[-93,-153],[-386,172],[-59,-142]],[[44403,80876],[-255,-252],[174,-230],[-190,-89],[42,-205],[-450,-186],[-31,174],[-412,-116],[-86,41],[32,530],[-271,0],[-77,326],[-230,-10]],[[45200,80589],[-264,-19],[-226,303],[-56,244],[-251,-241]],[[44403,80876],[-317,453],[-115,868],[-131,-216],[-105,123],[-228,-106],[-71,190],[-238,71]],[[45222,80588],[-207,827],[-109,-37],[62,264],[-449,604],[-353,-194],[-233,184],[-129,392],[-285,-26]],[[47967,16961],[-139,270],[-278,-53],[-342,125],[-159,164],[-316,187],[-20,80],[-566,412],[-93,120],[-533,145],[-241,378],[121,85],[91,317],[-296,-65],[-303,122],[-120,-73],[-400,113],[-388,210],[-378,80],[-231,-34],[-411,-240],[-595,351]],[[45182,8908],[-21,142],[94,377],[311,331],[12,201],[138,498],[134,209],[128,605],[-15,166],[-200,273],[135,417],[249,555],[-19,120],[120,336],[-25,153],[221,91],[164,162],[180,305],[21,185],[448,426],[-13,275],[100,5],[533,369],[-52,652],[-343,372],[12,152],[473,676]],[[43367,8545],[382,-33],[95,-86],[199,188],[416,45],[304,230],[419,19]],[[39222,16726],[-48,-330],[146,-322],[20,-539],[-140,-363],[-14,-329],[276,-865],[105,-143],[14,-477],[-199,-299],[176,-604],[287,-256],[48,-249],[-286,-348],[176,-316],[408,51],[302,-202],[142,-164],[309,-205],[262,-92],[258,-198],[288,-326],[284,-68],[252,-198],[537,-748],[388,-279],[154,-312]],[[41455,18454],[-33,-128],[-344,-294],[-339,-791],[-252,-143],[-286,-47],[-337,-229],[-642,-96]],[[42370,19655],[-314,-262],[-62,-351],[-235,-371],[-304,-217]],[[58387,29063],[-862,173],[-4,182],[-139,51],[-112,278],[-418,245],[-263,18]],[[59926,26560],[-111,73],[-420,542],[0,207],[-186,176],[-19,324],[85,174],[-173,-43],[-186,89],[-416,315],[-104,355],[-9,291]],[[59876,26204],[50,356]],[[50552,31260],[151,-126],[-80,-238],[17,-216],[270,46],[12,-224],[169,82],[93,-151],[196,11],[24,124],[227,-53],[97,128],[148,-43],[764,-11],[60,154],[652,302],[193,7],[301,-249],[68,-146],[574,-208],[298,-248],[12,-124],[302,-85],[71,-166],[178,-72],[38,-199],[-213,193],[-43,-195],[-321,4],[-8,-214],[200,-227],[574,-445],[155,-369],[-192,-492],[153,-281],[141,24],[-190,-337],[145,-294],[-198,-534],[-282,-625],[480,-56],[227,110],[17,208],[314,215],[538,234],[148,-192],[235,-514],[381,-143],[324,-43],[164,-240],[289,283],[608,173],[355,15],[488,391]],[[50636,33418],[249,-426],[282,-573],[62,-226],[196,-224],[-289,-294],[-443,-249],[-141,-166]],[[53396,32717],[-516,16],[-329,269],[-414,168],[-320,233],[-379,-5],[-120,103],[-380,-75],[-92,70],[-210,-78]],[[56589,30010],[-297,132],[-510,102],[-268,220],[-139,205],[52,132],[-275,49],[-176,272],[-287,144],[-265,206],[-167,299],[-496,184],[-332,345],[121,273],[-154,144]],[[49012,17925],[-166,292],[169,336],[281,133],[-67,442],[106,273],[-303,348],[-293,768],[64,218],[-140,642],[-12,762],[144,438],[376,655],[57,212],[240,-23],[108,84],[592,114],[296,-19],[-72,168],[123,10],[222,-207],[51,92],[178,-111],[259,100],[174,-91],[652,46]],[[47967,16961],[197,23],[643,413],[116,111],[89,417]],[[46882,28423],[-210,-441],[112,-331],[-121,-223],[-200,-199],[-74,-346],[-233,-345],[-18,-212],[-301,-337],[-188,-90],[3,-599],[-174,-429],[-292,-116],[-265,-464],[-69,-551],[-254,-650],[-46,-294],[-189,-342],[-123,-43],[-285,-287],[-168,46],[-354,-173],[-371,-384],[-136,-472],[-337,-514],[-22,-255],[-240,-300],[85,-303],[-42,-114]],[[52051,23607],[14,511],[-78,186],[88,160],[-284,195],[-62,126],[-174,-86],[-179,35],[17,491],[-211,392],[-33,276],[-238,178],[-148,25],[-101,155],[-252,81],[-9,227],[-221,-99],[-82,242],[-541,477],[-105,553],[-239,-154],[-398,198],[-337,238],[-295,140],[-373,24],[-50,162],[-451,349],[-263,-214],[-164,-52]],[[54384,19028],[-130,442],[-102,176],[-505,393],[-115,145],[-228,679],[33,222],[-148,24],[-231,270],[-117,401],[-149,25],[-184,245],[-226,119],[-90,651],[-77,193],[-64,594]],[[49012,17925],[613,-22],[526,-264],[89,136],[262,97],[54,-153],[185,141],[416,125],[37,-64],[354,92],[238,-251],[299,60],[106,215],[-78,193],[140,168],[-115,315],[219,230],[264,-39],[370,-394],[139,90],[467,-166],[235,64],[311,204],[241,326]],[[45182,8908],[128,-295],[318,-181],[328,-122],[111,296],[169,172],[-42,233],[-136,229],[155,216],[196,-32],[320,272],[140,321],[-15,264],[-105,322],[105,235],[535,111],[376,358],[104,332],[704,-447],[2612,-1128],[246,-172],[461,-174],[253,-44],[332,-558],[328,-219],[287,-303],[447,92],[152,314],[243,296],[602,112],[234,120],[60,153],[211,30],[305,317],[672,459],[86,186],[287,94],[231,197],[94,204],[137,-52],[258,283],[364,83],[90,354],[322,231],[92,236],[406,229],[371,496],[82,20],[1630,800],[190,380],[542,333],[402,352]],[[59475,16705],[-196,123],[-278,-64],[-163,45],[-481,-218],[-193,263],[-510,44],[-10,394],[-77,335],[-534,460],[-141,181],[-424,340],[-237,62],[-160,-88],[-361,51],[-347,139],[-337,32],[-642,224]],[[61602,14913],[-250,21],[-509,404],[-154,366],[59,136],[-363,131],[-344,45],[-396,391],[-170,298]],[[54073,33348],[-92,-124],[56,-265],[-198,33],[-281,-243],[-162,-32]],[[55359,32734],[-294,280],[-492,172],[-252,-29],[-248,191]],[[56589,30010],[-91,707],[-337,602],[-157,74],[-35,212],[-282,48],[-195,423],[11,124],[-144,534]],[[47900,30070],[-512,-426],[0,-267],[-344,-392],[0,-291],[-162,-271]],[[50552,31260],[-282,-160],[-273,152],[-194,-32],[-363,224],[-62,-179],[-262,-71],[-434,-825],[-203,-134],[-444,-179],[-135,14]],[[59475,16705],[254,36],[159,110],[211,431],[198,262],[164,592],[101,84],[-205,393],[-253,306],[-2,627],[-403,449],[-198,465],[11,435],[-252,393],[211,305],[180,70],[76,479],[182,140],[404,589],[-129,175],[-198,87],[364,374],[73,171],[-51,474],[115,448],[-150,283],[-23,287],[103,165],[-32,218],[-230,285],[9,157],[-288,209]],[[61295,38519],[-173,92],[-387,478],[-222,158],[1,127],[382,256],[-20,452],[-122,422],[-59,384],[36,235],[358,99],[386,371],[50,231],[504,84],[145,230],[-50,496]],[[58820,35195],[236,361],[316,-159],[211,-34],[266,190],[32,428],[483,529],[93,285],[155,244],[78,292],[-132,92],[137,225],[351,218],[239,448],[10,205]],[[56044,34758],[423,184],[344,8],[479,-54],[264,67],[709,342],[142,-157],[179,-31],[236,78]],[[59248,41573],[-72,-352],[-58,-589],[89,-295],[170,-171],[-201,-278],[-59,-252],[-259,-145],[-47,-163],[-216,-176],[22,-114],[-196,-138],[-175,-284],[-301,-246],[-2,-138],[-552,-395],[-328,-103],[-131,-164],[31,-167],[-272,-136],[-19,-277],[-398,-178],[-203,-212],[-41,-186],[-211,-62],[-91,-249],[-142,-119],[0,-205],[-105,-46],[79,-198],[571,-239],[70,-196],[-127,-129],[-30,-213]],[[60079,42550],[-189,-136],[-275,-332],[35,-45],[-321,-274],[-81,-190]],[[62124,42634],[-263,-61],[-775,-25],[-423,-248],[-165,172],[-419,78]],[[65182,33229],[17,-293],[338,-486]],[[63750,33769],[148,-1],[312,240],[191,77],[722,146],[280,-274],[-28,-198],[-133,-197],[-60,-333]],[[63796,33889],[-46,-120]],[[64357,35106],[-89,-489],[-161,-256],[-57,-231],[-254,-241]],[[64316,35934],[41,-828]],[[67585,36584],[-145,-163],[-416,-312],[-302,-34],[-511,-510],[-587,67],[-643,-39],[31,275],[-289,88],[-407,-22]],[[69145,35259],[-126,339],[-158,231],[-106,298],[-229,297],[-238,-6],[-149,198],[-554,-32]],[[65537,32450],[182,212],[261,54],[154,188],[337,219],[502,422],[227,77],[104,-83],[290,171],[145,14],[287,342],[56,166],[444,432],[194,297],[80,8],[345,290]],[[72166,34572],[120,-36],[287,102],[347,4],[78,-478],[326,-151],[337,-51],[325,223],[385,78],[457,365],[393,152],[444,419],[432,221],[-158,262],[93,439]],[[72138,39908],[89,-237],[-95,-233],[63,-93],[-187,-187],[184,-126],[-53,-213],[-258,-179],[509,-666],[176,-415],[208,-227],[-30,-345],[238,-176],[103,-328],[-128,-45],[-3,-234],[106,-157],[-70,-184],[-445,-200],[-247,-208],[-156,-377],[-55,-293],[79,-213]],[[71128,42161],[232,45],[442,-9],[521,281],[403,-225],[257,-30],[216,-139],[300,-8],[388,102],[328,-250],[190,-212],[-138,-293],[186,-212],[-143,-210],[89,-158],[-20,-193],[-335,-11],[-447,101],[-266,-132],[-66,-115],[-463,-48],[-343,-346],[-321,-191]],[[70330,44135],[-158,-220],[-225,-96],[-176,-260],[-188,-87],[-142,-220],[236,-258],[217,152],[169,-35],[94,116],[163,-272],[318,287],[135,-181],[145,-5],[75,-483],[135,-412]],[[74242,45356],[-500,43],[-231,173],[-242,75],[-315,-39],[-551,-187],[-325,-164],[-477,-305],[-501,-106],[-123,-105],[-51,-219],[-596,-387]],[[75465,41758],[-834,420],[-240,24],[-16,341],[-90,263],[-153,-20],[-52,248],[-222,453],[-33,222],[-21,965],[254,116],[148,340],[36,226]],[[76856,41348],[-204,-156],[-578,-119],[-193,-151],[-33,268],[-345,87],[-38,481]],[[77130,41315],[-283,-58],[9,91]],[[76874,39183],[123,367],[-128,377],[47,371],[67,-22],[94,333],[-102,-49],[58,568],[97,187]],[[76032,36121],[-205,-40],[-276,72],[-239,-175],[-218,110],[-216,-2],[-162,327],[197,541],[-26,292],[-161,265],[243,293],[482,29],[286,-100],[370,191],[325,485],[262,200],[168,39],[12,535]],[[76032,36121],[316,231],[53,120],[303,104],[119,136],[302,123],[86,-62],[650,397],[114,271],[542,692],[-95,113],[86,230],[-37,202],[311,383],[-18,364],[-231,157],[-219,-116],[-391,-17],[-24,-320],[-554,136],[-471,-82]],[[78961,43754],[-219,56],[-305,236],[-218,35],[-200,-89],[-285,88]],[[77130,41315],[337,80],[337,161],[74,-86],[338,2],[250,-76],[518,-23],[-5,-94],[280,33],[-149,407],[9,367],[-158,1668]],[[77734,44080],[-180,-39],[-316,-184],[-117,-468],[-349,-805],[-43,-427],[127,-809]],[[60962,33520],[-407,-284],[-48,31]],[[61557,33390],[-314,163],[-216,-169],[-65,136]],[[60711,32133],[314,540],[90,228],[260,163],[182,326]],[[59368,30400],[24,210],[633,752],[188,270],[198,150],[189,304],[111,47]],[[58307,32802],[161,-393],[-202,-538],[-12,-249],[99,-280],[211,-138],[142,-371],[171,-149],[491,-284]],[[60507,33267],[-233,-322],[-225,-140],[-284,-49],[-420,271],[-95,178],[-217,17],[-364,-150],[-362,-270]],[[80326,32507],[-258,-67],[-314,169],[-82,282],[-145,157],[205,292],[-189,245],[104,301],[-369,649],[9,146],[-357,239],[-250,327],[-414,114],[-531,2],[-111,-74],[-311,0],[-374,236],[-135,-3],[-145,247],[-627,352]],[[80310,28314],[-85,717],[210,476],[-204,451],[-196,217],[-646,112],[-137,186],[113,154],[207,89],[531,484],[88,147],[28,300],[-60,286],[167,574]],[[78674,21782],[299,327],[164,35],[182,296],[273,6],[62,152],[-167,450],[-230,232],[-238,674],[-23,512],[-120,157],[41,416],[602,358],[-107,417],[-138,100],[-404,125],[-324,449],[403,137],[368,183],[357,253],[270,489],[61,310],[159,386],[146,68]],[[71271,22892],[199,-73],[270,118],[168,176],[545,260],[375,-37],[153,-89],[515,23],[155,-214],[513,-302],[651,-67],[494,-420],[55,96],[369,25],[260,78],[234,176],[477,-323],[232,-88],[422,17],[110,-248],[408,-85],[201,62],[597,-195]],[[67407,28735],[308,-581],[22,-462],[263,-241],[230,-463],[-172,-533],[79,-248],[327,-27],[213,-92],[121,-190],[172,-38],[-12,-340],[199,-173],[68,-321],[367,-318],[21,-149],[362,-25],[242,137],[260,52],[345,156],[270,-111],[668,-1],[-55,-160],[135,-294],[29,-339],[-169,-438],[-394,-378],[-35,-266]],[[70006,33823],[-369,-271],[-704,-934],[272,-225],[417,76],[500,-230],[-242,-568],[-78,-393],[-112,-131],[-2,-319],[-193,-365],[-457,118],[-208,-101],[-319,83],[-11,-339],[149,-205],[23,-594],[-42,-190],[100,-194],[-651,54],[-672,-360]],[[72166,34572],[-33,-221],[-675,-149],[-121,129],[-415,-243],[-75,222],[-293,-324],[-106,128],[-442,-291]],[[64947,30246],[188,307],[-64,220],[85,252],[291,557],[269,315],[-179,553]],[[63389,33454],[-73,-71],[-125,-456],[-168,-190],[-9,-181],[140,-505],[157,-226],[223,-461],[589,-361],[218,-306],[369,-158],[52,-243],[185,-50]],[[65182,33229],[-128,180],[-215,-72],[-455,-348],[-92,-254],[-266,417],[-308,163],[-304,36],[-25,103]],[[67268,28774],[-77,147],[-5,568],[-129,247],[-204,638],[-41,383],[-117,215],[51,196],[142,55],[252,261],[204,-107],[72,414],[198,249],[122,326],[264,315],[310,280],[310,520],[650,310],[422,355],[214,0]],[[65257,28450],[470,21],[120,383],[116,155],[308,90],[159,-265],[493,48],[345,-108]],[[64947,30246],[119,-241],[236,-293],[77,-307],[-31,-333],[-94,-171],[61,-244],[-58,-207]],[[69906,34146],[479,282],[139,190],[173,472],[-3,196],[-118,328],[-77,7],[-417,-270],[-419,-159],[-285,43],[-179,119],[-54,-95]],[[63876,38420],[180,117],[383,117],[954,486],[91,116],[415,275]],[[61295,38519],[196,-216],[156,-434],[167,-98],[190,174],[1,149],[146,156],[168,15],[281,284],[245,164],[113,321],[198,-407],[227,224],[234,51],[259,-482]],[[62928,45130],[-16,-235],[75,-177],[-325,-252],[-202,-4],[-188,-297],[-118,-428],[132,-253],[-125,-243],[31,-530],[-68,-77]],[[68365,46010],[-319,133],[-668,-64],[-403,-190],[-831,-172],[-214,-224],[-132,48],[-680,-159],[-62,-101],[-468,-63],[-298,7],[-448,159],[-405,-18],[-120,-106],[-254,-26],[-135,-104]],[[68401,45764],[-36,246]],[[66531,40530],[219,327],[-169,113],[-308,374],[187,296],[523,402],[227,546],[201,61],[77,250],[207,121],[-28,131],[170,455],[77,79],[189,581],[-75,121],[20,324],[-75,173],[155,550],[251,188],[22,142]],[[65899,39531],[14,146],[269,383],[165,111],[184,359]],[[77734,44080],[-179,437],[-205,121],[-170,292],[-181,180],[-49,321],[-798,-174],[-190,33],[-334,228]],[[75628,45518],[-97,-454],[57,-146],[-47,-685],[82,-220],[-158,-2255]],[[64316,35934],[-155,23],[0,180]],[[60962,33520],[421,332],[403,487],[526,357],[44,188],[406,320],[305,8],[115,-224],[285,104],[890,14]],[[60661,33494],[-199,-125],[45,-102]],[[62585,37124],[-386,-447],[148,-339],[57,150],[161,-148],[100,-601],[-359,-54],[-196,-94],[-227,-578],[-144,-70],[-118,-241],[186,-48],[-145,-287],[-1001,-873]],[[64161,36137],[-296,-11],[-610,-131],[-670,1129]],[[72138,39908],[-539,-290],[-207,-177],[-460,-246],[-367,-281],[-107,-147],[-808,-688],[-500,-188],[35,198],[-206,-172],[-158,-333],[-379,-38],[-279,-182],[-495,-584],[-83,-196]],[[69906,34146],[100,-323]],[[62106,29078],[-227,-335],[-336,-667],[-166,-524],[11,-374],[-248,-323],[-505,-177],[-304,55],[-405,-173]],[[65257,28450],[-127,-163],[-302,-152],[272,918],[4,555],[-248,167],[-197,27],[-581,-252],[-309,36],[-138,-137],[-265,-47],[-228,115],[-286,-255],[-357,-213],[-203,-48],[-186,77]],[[67407,28735],[-139,39]],[[61602,14913],[297,92],[135,-150],[844,110],[395,-46],[532,86],[549,218],[238,243],[431,-85],[291,307],[283,134],[276,-27],[354,489],[380,1],[129,159],[-89,188],[254,217],[324,96],[116,498],[400,316],[55,122],[651,98],[90,-67],[280,150],[419,327],[188,2],[184,344],[48,248],[-45,229],[144,299],[-230,416],[-177,214],[54,161],[-151,122],[-158,317],[11,233],[314,228],[126,340],[615,310],[381,-32],[134,132],[348,719],[249,221]],[[58307,32802],[-291,-234],[-185,33],[-548,-130],[-284,-180],[-308,92],[-460,-162],[-497,210],[-375,303]],[[58387,29063],[201,314],[437,445],[152,404],[191,174]],[[61557,33390],[170,174],[207,-27],[100,148],[361,148],[-18,79],[644,85],[-48,204],[351,40],[472,-352]],[[63750,33769],[-361,-315]],[[67733,39201],[24,160],[-111,204],[-151,64],[-102,235],[-287,428],[-365,95],[-210,143]],[[66231,37820],[471,340],[519,466],[41,160],[471,415]],[[65899,39531],[158,-168],[-492,-278],[110,-21],[362,-472],[98,-278],[96,-494]],[[70330,44135],[-164,139],[-394,85],[-141,102],[-259,592],[-270,251],[-140,4],[-129,166],[-194,63],[-238,227]],[[67733,39201],[352,269],[263,400],[298,107],[92,288],[121,103],[214,5],[284,150],[214,265],[35,333],[355,225],[59,146],[166,37],[265,232],[205,38],[116,180],[356,182]],[[63876,38420],[-458,-392],[-53,-116],[-304,-236],[-476,-552]],[[64161,36137],[563,441],[265,393],[204,181],[450,151],[331,209],[257,308]],[[62106,29078],[-90,241],[102,339],[242,147],[135,217],[-161,-27],[-122,204],[262,201],[-15,408],[-192,160],[144,144],[-368,595],[-426,273],[-196,-78],[-320,61],[-101,-52],[-289,222]],[[75628,45518],[-110,-90],[-466,-136],[-301,198],[-300,-12],[-209,-122]],[[58820,35195],[368,-211],[279,-12],[171,-220],[-49,-149],[209,24],[167,-362],[200,-185],[409,-205],[85,-188],[-151,-159],[153,-34]],[[48573,57895],[358,113],[-8,96],[265,250],[55,255],[390,173],[157,-206],[195,-49],[830,459],[175,210],[312,4],[186,120],[48,271],[201,185],[200,-10],[66,297],[230,16]],[[48392,57941],[19,-144],[162,98]],[[47683,60210],[11,-166],[185,-81],[-229,-244],[559,97],[283,211],[84,-193],[132,-568],[-137,-357],[-254,-7],[-25,-212],[129,-51],[-13,-165],[-128,8],[-43,-242],[155,-299]],[[48893,61509],[-48,7],[-185,-620],[-321,-27],[-157,-238],[88,-112],[-285,-126],[-148,90],[-18,-175],[-136,-98]],[[52258,60203],[-274,57],[-243,-96],[-94,363],[-393,-10],[-276,71],[-192,196],[-335,224],[-427,-15],[-240,-210],[-486,196],[-125,-22],[3,230],[-220,-109],[-84,217],[21,214]],[[52233,60079],[25,124]],[[47138,59456],[-86,-312],[-189,-196],[87,-58],[-46,-272],[165,-217],[152,81],[12,-232]],[[47683,60210],[-155,7],[-19,-290],[-293,-115],[17,-379],[-95,23]],[[47233,58250],[325,-219],[361,96],[210,-37],[78,-187],[185,38]],[[51480,54530],[163,35],[-16,-438],[-162,-299],[-51,-318],[-170,-362],[263,-211],[234,-298],[-25,-103]],[[50733,57279],[79,-423],[-136,-379],[136,-59],[-32,-292],[-121,-164],[237,-381],[250,-72],[249,257],[178,-45],[-76,-325],[207,-122],[-134,-177],[-87,-275],[73,-107],[-76,-185]],[[53095,57411],[-374,-144],[-347,-344],[-178,-27],[-256,114],[-354,-133],[-75,113],[228,326],[-118,121],[-433,-326],[-210,-225],[-19,249],[-226,144]],[[54348,55293],[88,223],[-236,557],[56,172],[-168,350],[-302,263],[-142,214],[-154,-175],[-341,121],[131,342],[-185,51]],[[53256,52915],[282,97],[-172,90],[23,159],[-172,260],[-1,145],[-156,176],[4,176],[-121,227],[261,292],[236,64],[216,293],[331,150],[361,249]],[[51716,52536],[163,100],[259,-41],[373,215],[110,-47],[190,135],[169,-78],[276,95]],[[46565,48408],[-158,-75],[190,-721],[1,-382]],[[48088,48456],[-624,198],[-459,-222],[-34,133],[-164,7],[-15,-161],[-227,-3]],[[47572,47133],[-2,373],[255,404],[83,399],[180,147]],[[47444,47128],[128,5]],[[46598,47230],[335,162],[205,-187],[306,-77]],[[48890,51957],[28,48]],[[47073,51969],[99,83],[236,-58],[107,194],[326,-10],[127,-210],[143,169],[298,-221],[481,41]],[[47431,52821],[-54,-240],[-304,-612]],[[48002,53662],[-165,-191],[-246,36],[139,-454],[-126,-24],[-173,-208]],[[48918,52005],[117,365],[-18,202],[-218,170],[54,223],[183,241],[-213,77],[-338,256],[-77,-110],[-406,233]],[[49254,56897],[-305,150],[-327,245],[-49,603]],[[49019,56285],[22,355],[161,-9],[52,266]],[[48483,56069],[235,239],[301,-23]],[[45878,57237],[3,-190],[348,-24],[123,-368],[393,-568],[245,39],[25,-177],[222,-255],[210,55],[400,271],[287,-56],[114,-102],[-7,265],[242,-58]],[[45809,57420],[69,-183]],[[47233,58250],[-154,-25],[83,-273],[-51,-302],[-96,-10],[-49,-218],[-150,-53],[36,152],[-160,-22],[-54,238],[-395,253],[-88,-137],[-332,-23],[190,-145],[-69,-284],[-135,19]],[[46414,52972],[-238,182],[-256,-90],[-140,-146],[-124,40],[-29,-184],[-161,-30],[-96,-171]],[[47431,52821],[-152,-79],[-397,-37],[-155,45],[-313,222]],[[46555,50847],[374,-36],[104,468],[-88,202],[128,488]],[[45370,52573],[103,-61],[245,-480],[132,108],[73,-372],[587,-191],[180,-149],[-30,-308],[-105,-273]],[[45556,49589],[94,-327],[175,43],[404,-321],[83,111],[113,-143],[140,-544]],[[46314,50041],[-137,8],[-103,-189],[-259,197],[63,-429],[-322,-39]],[[48088,48456],[285,-38],[78,410],[-546,100],[-379,32],[-420,289],[-351,421],[-151,396],[-290,-25]],[[45155,49370],[-464,-186],[-567,-275]],[[45684,46554],[59,374],[-17,315],[-203,350],[114,212],[-227,458],[12,123],[-128,415],[-4,226],[-135,343]],[[45095,46174],[-71,294],[208,448],[182,11],[59,-442],[211,69]],[[44167,47253],[66,-630],[220,-246],[642,-203]],[[44124,48909],[212,-291],[52,-377],[-89,-275],[-132,-713]],[[45878,57237],[-232,-178],[-234,-380],[-105,4],[128,-299],[-155,159],[-46,-167],[-156,38],[-14,-164],[131,-257],[-252,-157],[-149,-387],[-99,-34],[19,-307],[214,-136],[-3,-259],[172,-59],[149,-220],[872,-491],[-33,-201],[338,-335],[164,-306],[-173,-129]],[[48761,55138],[99,261],[-139,51],[-212,278],[127,208],[-153,133]],[[48002,53662],[-4,125],[-301,262],[5,216],[315,437],[744,436]],[[49660,62293],[-213,-90],[-333,-503],[-140,5],[-81,-196]],[[51444,63427],[-113,-117],[-185,117],[-259,-226],[-20,-148],[-413,-154],[-162,-286],[-177,-95],[-166,-218],[-187,-102],[-102,95]],[[52518,61905],[-58,601],[95,327],[-138,161],[1,155],[-165,-26],[-204,-205],[-450,124],[-155,385]],[[52258,60203],[139,87],[158,246],[17,207],[162,292],[-202,472],[-14,398]],[[53043,50088],[31,356],[-95,300],[49,128],[213,56],[273,-71],[292,167],[-161,338],[-104,401],[77,140],[-82,516],[-140,251],[-155,122],[15,123]],[[50695,49325],[137,-149],[162,145],[-69,257],[129,148],[151,-130],[1838,492]],[[48890,51957],[-142,-273],[228,-6],[114,-293],[-13,-258],[128,-16],[29,-273],[-99,-167],[216,95],[590,62],[581,-669],[100,15],[8,-267],[218,147],[50,-263],[-86,-303],[-117,-163]],[[50384,52278],[-463,-295],[-303,-135],[-354,-36],[-346,193]],[[51716,52536],[-197,-108],[32,-255],[-301,-48],[45,-127],[-664,-16],[-40,169],[-207,127]],[[50057,55050],[21,320],[-249,-131],[-166,429],[130,71],[-76,326],[-220,125],[-478,95]],[[49334,54656],[342,12],[114,-100],[131,78],[136,404]],[[48761,55138],[573,-482]],[[42393,54149],[133,-497],[251,-625]],[[43959,57260],[-91,-146],[80,-311],[-93,-63],[108,-697],[-72,-265],[-212,-82],[-133,180],[-338,-134],[94,-319],[-173,-119],[143,-318],[-483,-247],[6,-137],[-402,-453]],[[45809,57420],[-429,-3],[-192,109],[-67,-170],[-436,-47],[-18,115],[-201,114],[-91,-203],[-262,39],[-154,-114]],[[43318,51748],[121,56],[-59,170],[350,234],[-18,187],[466,96],[84,140],[735,-7],[84,-185],[289,134]],[[42777,53027],[541,-1279]],[[50384,52278],[282,175],[-333,322],[-165,18],[-384,349],[-170,27],[-36,181],[-152,94],[-257,382],[356,517],[-144,114],[-47,199]],[[47572,47133],[83,-67],[332,145],[267,-121],[112,110],[373,103],[78,-60]],[[46555,50847],[-142,-144],[-99,-662]],[[48817,47243],[115,270],[289,268],[-16,300],[291,162],[43,667],[698,-18],[193,118],[265,315]],[[52243,59484],[-10,595]],[[53095,57411],[63,115],[-465,110],[178,199],[-198,253],[106,430],[-19,296],[-474,539],[-43,131]],[[49254,56897],[325,171],[263,300],[161,-42],[130,101],[121,-62],[63,-221],[416,135]],[[45556,49589],[-201,-8],[-231,-138],[31,-73]],[[45684,46554],[277,129],[395,376],[242,171]],[[40806,57083],[518,-440],[748,-1067],[207,-648],[114,-779]],[[42419,57360],[-113,-74],[-573,24],[132,-193],[-101,-106],[-274,182],[-170,-151],[-274,242],[-240,-201]],[[43959,57260],[-134,191],[-242,42],[-41,-126],[-269,82],[-190,-178],[-445,-80],[-219,169]],[[49660,62293],[-8,109],[252,312],[-185,388],[221,299],[6,496],[-240,138],[8,224]],[[46047,61223],[-179,-60],[-85,-266],[91,-23],[-115,-286],[-207,-174],[-17,-192],[132,-200],[518,-56],[382,-243],[143,-13],[206,-243],[222,-11]],[[41240,58785],[221,-69],[242,36],[-1,-148],[-228,-67],[311,-288],[162,100],[202,-421],[81,44],[22,-446],[167,-166]],[[50057,55050],[403,-589],[457,-233],[88,236],[196,121],[279,-55]],[[40110,57824],[365,-468],[331,-273]],[[43858,49459],[266,-550]],[[43766,49704],[92,-245]],[[43318,51748],[72,-587],[147,-827],[229,-630]],[[21460,62176],[295,-326],[-136,-214],[-73,-508],[150,-134],[-40,-582],[-105,20],[-266,-150],[39,-306],[388,-627],[80,18],[60,-273],[-100,-145]],[[22598,62470],[-1138,-294]],[[23765,62218],[-301,8],[132,291],[-298,41],[-93,-242],[-440,34],[-167,120]],[[23636,59354],[334,863],[-29,179],[-564,715],[-163,357],[119,216],[305,278],[127,256]],[[23211,59538],[425,-184]],[[22092,59015],[-71,304],[202,105],[-71,125],[508,316],[241,55],[-74,188],[126,111],[286,-165],[-28,-516]],[[21752,58949],[340,66]],[[23120,57867],[57,395],[-167,126],[147,279],[-109,173],[139,-4],[14,346]],[[22218,58689],[-51,-135],[240,-368],[108,5],[-90,-327],[327,-5],[-14,-176],[382,184]],[[23201,59182],[-210,13],[-150,-174],[-186,-48],[-437,-284]],[[27724,62555],[71,-301],[-134,-115],[123,-199],[64,-486],[-219,-56],[37,-934],[91,-215]],[[22598,62470],[-12,81],[286,22],[-125,263],[-271,365],[113,208],[-107,212]],[[22482,63621],[-357,-183],[-137,-136],[-29,-432],[-424,59],[-63,-332],[-681,-3],[-64,-267],[339,-224],[394,73]],[[22218,58689],[-126,326]],[[22952,56684],[192,306],[-30,388],[105,203],[-99,286]],[[21752,58949],[0,-168],[-262,-44],[-7,-277],[-110,-28],[110,-377],[-55,-510],[113,-347],[-159,-85],[-60,-191],[-348,-249],[-206,-61],[-494,-265],[481,-140],[98,191],[194,147],[249,-48],[240,64],[294,-90],[319,-432],[285,439],[165,133],[353,73]],[[23211,59538],[-10,-356]],[[23631,58157],[-76,9],[-66,496],[21,317],[126,375]],[[24611,56124],[76,514],[-34,534],[-194,202],[-226,95],[31,180],[-178,-77],[-440,451],[-15,134]],[[22952,56684],[105,-358],[270,-217],[427,-18],[75,241],[344,-129],[438,-79]],[[23631,58157],[406,-45],[156,-103],[275,119],[323,247],[127,166],[332,116],[386,-27],[276,-189],[1097,92]],[[24612,64025],[-255,-114],[-89,-233],[36,-454],[-38,-219],[-305,-429],[-196,-358]],[[15952,56558],[61,-181],[210,-36],[15,152],[251,265],[477,300],[225,0],[-181,461],[25,407],[-76,296],[-438,-117],[-151,78],[-655,-305],[-103,-518],[369,-485],[-92,-55],[63,-262]],[[24611,56124],[287,-108],[310,-352],[439,-138],[379,-242],[264,68],[175,220],[259,114],[300,-1],[702,-213],[367,5],[726,182],[228,-13],[793,-265],[425,-109],[284,-151],[123,-227]],[[22987,64195],[-135,-192],[-427,-287],[57,-95]],[[34787,95751],[-241,-116],[-523,20],[-669,-288]],[[34328,93604],[-23,124],[158,339],[-67,48],[-26,708],[239,235],[258,101],[1,314],[-81,278]],[[33141,93827],[126,-93],[183,-296],[295,7],[288,119],[295,40]],[[33354,95367],[64,-49],[-136,-218],[-311,-341],[3,-254],[162,-334],[5,-344]],[[27859,90806],[404,219],[530,142],[397,274],[539,-86]],[[26815,90499],[1044,307]],[[26209,92231],[70,-621],[81,-347],[464,-667],[-9,-97]],[[27043,92464],[-419,17],[-346,92],[63,-277],[-132,-65]],[[29795,92472],[-860,68],[-450,-89],[-75,111],[-348,-146],[-504,102],[-140,-67],[-375,13]],[[29729,91355],[66,252],[150,144],[17,153],[-254,-36],[-64,277],[18,264],[133,63]],[[38477,93436],[446,567],[145,-10],[475,264],[-39,134]],[[38248,96235],[-45,-329],[-379,-275],[-16,-93],[-454,53],[-321,-552],[25,-192],[-85,-312],[-218,64],[-77,-411],[135,-122],[29,-191],[143,20],[234,-164],[91,-181],[305,24],[553,-235],[309,97]],[[39264,95757],[-322,25],[-478,274],[-10,102],[-206,77]],[[39504,94391],[-338,205],[230,385],[-267,543],[135,233]],[[33138,91331],[-134,-180],[-355,108],[-516,-22],[-347,93],[-126,147],[-228,-90],[-66,-145],[-469,-229],[-204,-204],[-275,-175],[-215,-213],[-130,409],[-168,305],[-134,21],[-42,199]],[[34625,90850],[-96,145],[-321,-156],[-340,-50],[-344,150],[-152,305],[-234,87]],[[29891,87458],[370,155],[680,185],[129,-143],[182,1],[198,119],[567,591],[362,191],[1109,459],[224,139],[390,415],[295,152],[175,-46],[336,263],[-170,244],[-122,512],[9,155]],[[27859,90806],[127,-206],[-33,-473],[39,-141],[383,-60],[83,-388],[209,-113],[30,-1031],[100,-122],[-266,-127],[411,-432],[141,-445]],[[36456,91921],[332,-11],[603,150],[319,16],[223,222],[257,478],[144,445],[143,215]],[[36134,96384],[24,-234],[141,-302],[-183,-83],[-193,-390],[105,-41],[-22,-252],[-381,-111],[-58,-384],[84,-373],[-42,-343],[72,-18],[-63,-393],[178,4],[27,-133],[182,123],[243,-337],[82,-391],[-41,-357],[167,-448]],[[38248,96235],[-480,29],[-454,-67],[-705,162],[-475,25]],[[33141,93827],[0,-445],[-194,-308],[42,-249],[209,-436],[1,-379],[-61,-679]],[[35781,91594],[-39,145],[-313,-239],[-259,-5],[111,356],[-132,338],[-333,325],[-70,348],[-418,742]],[[34625,90850],[153,234],[499,150],[504,360]],[[35781,91594],[382,311],[293,16]],[[34939,96216],[-30,-399],[-122,-66]],[[36134,96384],[-731,-128],[-181,52],[-283,-92]],[[22866,89560],[136,-85],[338,-48],[241,-878],[486,-1276],[183,42]],[[23662,91569],[-504,-337],[-104,-115],[-27,-326],[23,-472],[-112,-73],[100,-171],[-29,-324],[-143,-191]],[[24056,91653],[-265,-140],[-129,56]],[[24250,87315],[112,55],[-7,383],[-121,663],[-101,242],[-30,358],[52,751],[-132,97],[139,232],[-6,455],[-73,405],[13,451],[-40,246]],[[27814,94367],[237,53],[510,-27],[-8,-116],[291,35],[356,147],[47,-155],[344,95],[234,-590],[485,-105],[96,-307],[70,41],[284,-709],[-505,-119],[-176,10],[-284,-148]],[[30387,96106],[-227,-36],[-439,60],[-310,-419],[-52,-196],[-564,-403],[-355,-505],[-397,-107],[-229,-133]],[[33354,95367],[-859,-285],[-308,40],[-171,-110],[-1076,-173],[-60,151],[-504,-196],[-114,235],[-227,-115],[-74,197],[53,191],[327,76],[174,134],[-128,594]],[[26134,94022],[0,-50],[947,-388],[18,-405],[-76,-264],[20,-451]],[[27814,94367],[-327,-38],[-609,-169],[-744,-138]],[[24295,86944],[-45,371]],[[19759,89381],[634,-211],[655,-43],[61,-241],[232,-229],[178,-76],[264,50],[284,-430],[-45,-58],[493,-888],[57,-214],[-203,-257],[165,-200],[241,124],[51,-193]],[[22067,89718],[-204,-114],[-109,178],[-666,-178],[-462,-220],[-412,114],[-40,93],[-305,-87],[-110,-123]],[[22866,89560],[-130,193],[-341,6],[-98,99],[-230,-140]],[[34939,96216],[-94,177],[-425,133],[-80,326],[-366,-66],[-776,86],[-176,-40],[-632,92],[-109,93],[-820,-545],[-320,-75],[-754,-291]],[[22067,89718],[-120,17],[46,435],[-61,225],[-227,218],[-169,295],[-53,245],[271,146],[-82,173]],[[18242,89391],[770,-35],[98,-126],[160,29],[117,-120],[372,242]],[[19203,93095],[-516,-259],[-302,-59],[-426,-235],[-192,-364],[99,-265],[109,57],[-176,-327],[-194,-38],[-22,-367],[341,48],[220,-144],[-161,-91],[251,-282],[157,-339],[-332,-112]],[[21672,91472],[-455,-129],[-112,-110],[-168,85],[-304,-142],[-426,81],[53,143],[-104,332],[-336,429],[7,317],[-68,261],[-211,-121],[-107,308],[-238,169]],[[23662,91569],[-263,305],[-82,262],[-400,23],[-336,-115],[-175,-176],[-442,-108],[-89,-242],[-203,-46]],[[43463,97747],[209,-92],[437,287],[180,274],[32,179],[-770,1345],[-196,-57],[-11,174],[-266,142],[-138,-232],[-1,-205],[-291,-125],[-672,-496],[-63,-329],[-193,-358],[-160,-479],[231,-155],[1004,49],[408,165],[260,-87]],[[39504,94391],[228,14],[441,245],[33,-79],[485,236],[445,150],[229,-22],[516,78],[414,400],[-29,331],[490,403],[85,1009],[622,591]],[[43463,97747],[-479,-248],[-1286,-349],[-494,-258],[-444,-401],[-308,-226],[-438,-207],[-426,-303],[-324,2]],[[26815,90499],[10,-252],[345,-561],[34,-396],[-148,-134],[78,-1055],[-150,-479],[144,5],[-1,-174]],[[21792,94472],[-247,310],[186,266],[-198,76],[-712,36],[-423,-99],[-149,43],[-698,-113],[-332,46],[-314,-43],[-25,-95],[293,-142],[25,-92],[-236,-171],[29,-256],[237,-37],[75,-284]],[[19303,93917],[245,-18],[453,68],[428,134],[622,86],[741,285]],[[19303,93917],[-147,-171],[47,-651]],[[26134,94022],[-134,-20],[-632,170],[-289,121],[-292,-31],[-3,-117],[-331,-41],[-645,7],[-191,49],[-450,245],[-549,-4],[-508,178],[-318,-107]],[[24056,91653],[223,-58],[54,264],[153,147],[827,205],[320,-131],[576,151]],[[14041,74154],[-631,-546],[195,-218],[43,-238],[-13,-477],[313,-368],[123,-292],[497,263],[854,377],[224,445],[102,321],[567,393],[138,152],[529,316]],[[16520,74806],[-720,-606],[-446,581],[-412,-138],[-341,-303],[-560,-186]],[[16982,74282],[-128,302],[-334,222]],[[13861,74814],[486,245],[-102,209],[121,128],[282,68],[129,237],[-101,859],[-259,23],[123,148],[-37,165],[247,211],[-92,511],[-112,-12],[32,522],[157,143],[354,118],[186,176],[134,308],[243,254],[313,243],[495,295],[352,151],[639,348],[232,26],[529,232]],[[11118,78400],[-539,-490],[-496,-727],[323,-839],[745,520],[34,-63],[506,-335],[488,-523],[382,-15],[775,-327],[525,-787]],[[13861,74814],[167,-253],[13,-407]],[[17364,76706],[67,183],[141,-10],[474,375],[241,489],[315,111],[385,245],[61,197],[236,25],[229,145],[113,-163],[499,90],[173,230],[382,266],[191,44],[276,309]],[[16520,74806],[460,466],[183,38],[353,454],[-293,319],[20,595],[121,28]],[[26253,76838],[311,248],[134,-46],[195,267],[164,108],[-184,309],[419,272]],[[26119,76799],[134,39]],[[25602,77602],[36,-361],[253,-362],[228,-80]],[[27146,78529],[-201,-139],[-768,-340],[-575,-448]],[[27292,77996],[-146,533]],[[25356,76586],[-189,349],[-363,-31],[-241,-174],[-74,129],[-221,-42],[-120,211],[89,112],[-251,130],[-124,-94]],[[24325,75540],[-21,226],[212,140],[-100,158],[168,79],[-136,204],[129,122],[307,95],[472,22]],[[23347,75169],[618,411],[-25,-369],[94,-30],[71,194],[220,165]],[[22803,75100],[227,-32],[101,-131],[216,232]],[[22661,76867],[-137,-108],[448,-302],[-94,-176],[227,-64],[75,-413],[-69,-225],[-164,64],[106,-402],[-96,135],[-154,-276]],[[23862,77176],[-388,-168],[55,-86],[-282,-174],[-78,-120],[-281,26],[-227,213]],[[24508,78104],[10,-280],[715,-319],[369,97]],[[27569,78986],[-168,-64],[-247,187],[-375,464],[119,110],[-273,158],[-289,62]],[[27146,78529],[423,457]],[[23471,73230],[-106,-160],[59,-112],[-234,-203]],[[24795,73022],[-199,124],[77,191],[-338,371],[-80,-86],[-144,126],[-586,-432],[-54,-86]],[[23190,72755],[43,-244],[135,106],[-8,-175],[135,-246],[-96,-102],[52,-214],[186,-73],[291,-330],[132,292],[167,-153]],[[23471,73230],[-528,457],[-136,183],[-65,-148],[-80,356]],[[21976,72179],[335,150],[53,-62],[534,221],[292,267]],[[21718,73530],[-253,-384],[53,-102],[-196,-83],[101,-388],[218,-313],[21,-221],[314,140]],[[22662,74078],[-944,-548]],[[20882,70898],[-585,476],[118,198],[111,-131],[182,179],[-32,200],[-145,156],[100,223],[-296,-18],[-290,-203],[-407,359]],[[21308,70657],[-453,195],[27,46]],[[19638,72337],[-105,-265]],[[24979,73481],[-111,55],[140,217],[-392,337],[-214,98],[-94,241],[-76,-60],[-225,182],[-244,94],[-75,157],[-341,367]],[[22656,74323],[6,-245]],[[22803,75100],[16,-247],[-163,-530]],[[26361,75358],[130,181],[-239,316],[-172,-9],[500,280],[-168,28],[-120,283],[476,154],[-118,137]],[[24325,75540],[96,-269],[279,-68],[-45,-132],[330,-375],[130,168],[-22,-192],[346,-327]],[[26119,76799],[-75,-82],[-374,-111],[-314,-20]],[[26650,76728],[-331,-62],[-66,172]],[[22865,78258],[34,-85],[-467,-568],[-52,-132]],[[23785,77817],[-345,-194],[-273,562],[-302,73]],[[23862,77176],[-83,369],[6,272]],[[22380,77473],[93,-181],[189,-128],[-80,-136],[79,-161]],[[16982,74282],[485,350],[227,102],[166,239],[353,157]],[[18213,75130],[-361,386],[-79,293],[-349,279],[-95,472],[35,146]],[[21051,74239],[258,-168],[319,-310],[90,-231]],[[21292,74979],[-96,-594],[-145,-146]],[[22656,74323],[-421,336],[-7,205],[-161,87],[-102,355],[-343,-240],[-77,124],[-253,-211]],[[23785,77817],[272,26],[187,441],[152,-70]],[[23389,78904],[-127,5],[-54,-256],[-343,-395]],[[28953,79766],[-163,157],[-115,-75],[-165,241],[-244,212],[19,199],[-155,312],[-125,-75],[-155,98],[-153,243],[-140,-81],[-190,70]],[[28117,79413],[399,141],[437,212]],[[27569,78986],[280,292],[268,135]],[[28953,79766],[144,-294],[238,-174],[131,20],[16,467]],[[28117,79413],[181,-422],[96,70],[67,-200],[-183,-180],[79,-240],[203,147],[156,-118],[29,-180],[227,-68],[126,178],[-239,330],[146,146],[89,-108],[184,180],[298,-365],[455,395]],[[27292,77996],[203,105],[262,-539],[268,-61],[432,22],[-59,-166],[345,-168]],[[26650,76728],[164,88],[230,-203],[154,59],[133,-203],[215,187],[111,-233],[88,226],[412,-244]],[[22380,77473],[-189,-668],[0,-186],[-317,-289],[4,-116],[-163,-386],[-345,-457],[-78,-392]],[[21051,74239],[-373,-721],[-148,-468],[-338,-531],[-332,-72],[-199,90],[-23,-200]],[[20882,70898],[109,214],[-53,86],[393,120],[212,228],[-52,197],[511,266],[-26,170]],[[18213,75130],[311,254],[437,187],[542,408],[160,62],[110,308],[311,388],[633,424],[420,433],[307,242],[634,766]],[[16238,71505],[374,311],[321,202],[341,514],[400,377],[209,359],[-206,298],[-266,86],[-109,-195],[40,-206],[-320,-766],[-556,-242],[-207,-347],[-206,-104]],[[36776,37102],[-262,-541]],[[37445,37267],[-330,-222],[-174,93],[-165,-36]],[[39519,37160],[-399,-166],[-225,116],[-260,-86],[-363,256],[-338,29],[-314,-81],[-175,39]],[[41884,36755],[-108,117],[-169,-31],[-532,86],[-44,89],[-357,13],[-51,131],[-299,176],[-291,23],[-301,-171],[-213,-28]],[[42224,36058],[-99,30],[-189,419],[-52,248]],[[38154,28653],[-124,157],[-45,415],[182,431],[174,130],[408,122],[226,-161],[68,158],[88,-183],[236,-88],[-6,284],[-177,208],[50,97],[299,63],[104,239],[414,522],[127,268],[478,67],[238,-9],[-36,292],[190,586],[-143,-8],[-23,485],[165,34],[-141,298],[33,205],[-219,249],[-104,409],[-4,545],[178,282],[-316,138],[46,258],[-187,301],[63,128],[536,77],[860,335],[225,-25],[207,96]],[[37855,28224],[168,85],[27,239],[104,105]],[[36514,36561],[289,-285],[235,-16],[289,-507],[65,-428],[113,-12],[67,-366],[20,-457],[164,-320],[-162,-257],[-33,-303],[41,-304],[202,-103],[353,-488],[14,-214],[296,41],[-118,-396],[35,-192],[-484,-339],[-65,-156],[-326,-197],[-59,-116],[194,-228],[36,-215],[-433,-22],[10,-260],[223,39],[67,-162],[167,-95],[-133,-203],[175,-488],[-130,-31],[-143,-293],[238,-273],[110,-346],[-52,-298],[76,-47]],[[36518,20413],[93,-56],[159,124],[173,-12],[61,-130],[271,27],[365,194],[209,-223],[410,-14],[545,-77],[27,-177],[158,-181],[385,-56],[184,-234],[270,-19],[392,-581],[303,-277],[98,65],[273,-85],[228,-221],[152,57],[181,-83]],[[35661,26558],[645,-707],[736,-721],[-117,-79],[-87,-241],[121,-176],[321,-176],[150,-203],[-70,-334],[131,-194],[-429,-500],[-255,-5],[-154,-285],[-140,14],[-59,-175],[-276,-462],[-119,-527],[168,-287],[329,-275],[285,-135],[-28,-264],[-257,-162],[-38,-251]],[[35786,26642],[-125,-84]],[[37855,28224],[-232,-132],[-442,-139],[-262,-167],[43,-190],[-176,-67],[-72,89],[-86,-236],[-397,-427],[-256,-100],[-189,-213]],[[46642,33557],[-376,-145],[-640,-412],[-359,-86],[-258,79],[-315,-223],[-598,42],[-61,-373],[-253,-112],[20,-284],[-133,5],[-598,-145],[-126,20],[-406,-118],[-270,-243],[58,-337],[-120,-367],[-81,-29],[-32,-1030],[-129,-317],[-277,-184],[-200,-242],[-36,-164],[-140,39],[-203,-142],[-450,42],[-64,162],[-274,-32],[-41,147],[-446,-309],[-402,95],[-432,-265],[-242,144],[-337,-199],[-267,79]],[[47900,30070],[-29,139],[-479,437],[-79,411],[-174,511],[-320,297],[30,241],[-92,253],[101,318],[152,172],[-286,148],[-126,300],[44,260]],[[44492,35569],[-392,181],[-527,-44],[-436,185],[-204,2],[-151,210],[-558,-45]],[[47184,34500],[-166,-34],[-533,61],[-111,-66],[-247,55],[-25,105],[-211,-33],[-277,145],[-170,178],[33,151],[-683,-12],[-354,154],[52,365]],[[46642,33557],[353,97],[121,351],[68,495]],[[32124,32313],[62,-242],[220,-183],[-71,-138],[-243,-155],[-360,-393],[286,-92],[304,209],[227,232],[595,315],[571,140],[47,-352],[231,-266],[-43,-80],[372,-142],[409,182],[-38,-330],[-104,-78],[-26,-252],[173,-56],[212,-575],[167,73],[16,-145],[-119,-423],[60,-124],[-101,-732],[102,-150],[233,-91],[209,23],[14,-916],[237,-500],[-101,-293],[121,-137]],[[32098,34197],[-335,-553],[86,-182],[-83,-381],[44,-98],[-53,-356],[-112,-339],[479,25]],[[34071,35534],[80,-390],[82,-123],[-256,-523],[39,-302],[-215,-267],[-309,143],[-105,187],[-200,-124],[-51,-179],[-248,-134],[-286,-2],[-371,344],[-133,33]],[[36514,36561],[-315,6],[-371,177],[-205,196],[-111,-322],[-402,-182],[-336,3],[-6,-486],[-697,-419]],[[48139,37583],[-281,244],[-522,118],[-282,198],[-345,357]],[[48267,35744],[-106,185],[7,636],[141,363],[-17,373],[-153,282]],[[47184,34500],[226,58],[175,175],[36,159],[696,621],[-50,231]],[[46264,38000],[-135,-285],[129,8],[33,-327],[-217,199],[-524,21],[219,-148],[-234,-352],[-228,-234],[-148,-352],[-144,-36],[-73,-236],[-316,-506],[-31,-200],[-103,17]],[[46709,38500],[-445,-500]],[[47753,38825],[-129,-125],[93,-240],[426,-463],[122,-217],[-126,-197]],[[54073,33348],[-132,198],[-208,-5],[-93,127],[-518,172],[-267,140],[-192,186],[114,633],[-76,176],[-421,290],[-349,66],[-350,129],[253,70],[-113,143],[42,215],[-437,208],[-799,97],[-361,204],[-155,432],[-341,372],[-746,550],[41,278],[-49,183],[78,152],[-215,274],[-132,-242],[-223,-49],[228,285],[-227,48],[-125,-74],[-209,101],[-62,-80],[-95,237],[-181,-39]],[[48267,35744],[135,-199],[246,152],[271,-144],[34,-130],[453,-127],[394,-183],[174,-160],[6,-122],[202,-240],[74,-298],[140,-198],[37,-205],[203,-472]],[[46264,38000],[-212,61],[-856,130],[-353,238],[33,170],[-414,244],[68,54],[-173,309],[43,278],[-326,297],[-53,352]],[[42504,39322],[124,-222],[-158,-149],[306,-264],[-62,-163],[126,-155],[18,-601],[-178,-217],[-109,-493],[-687,-303]],[[44021,40133],[-300,3],[-326,-250],[-374,-43],[-256,-298],[-261,-223]],[[94799,30553],[-146,223],[-337,360],[-6,227],[-127,201],[-77,426],[-219,310],[-266,82],[-324,275],[-56,125],[-239,140],[37,285],[-208,58],[-209,164],[-18,113],[-330,286],[-58,588],[-142,92],[-340,76],[-192,268],[-375,260],[-98,315],[90,130],[23,410],[-94,202],[-248,17],[-395,175],[-411,-60],[-617,236],[-181,21],[-383,-340],[-187,-444],[-250,-226],[32,-359],[-338,191],[-60,-212],[-194,-147],[-164,-342],[-324,-120],[-16,143],[-304,-56],[-264,-191],[-122,15],[-509,-124],[-245,-272],[-7,-292],[-130,-790],[185,-583],[441,-326],[262,-306],[131,-254],[120,-41],[91,-234],[336,-315],[360,-517],[9,-271],[-77,-645],[-184,-282],[10,-350],[-313,-248],[-96,-345],[-168,-246],[-219,-100],[-239,-592],[-67,-381],[101,-255],[315,-337],[-238,-574],[-263,59],[-279,-216],[-363,12],[-439,125],[-127,-118],[-471,97],[-151,-67],[-229,110],[-244,-121],[-217,88],[-163,-99],[-485,128],[-179,304],[-636,376],[-161,349],[-352,198],[-148,253],[-457,237],[-271,299],[17,78],[-334,285],[-269,147]],[[78674,21782],[214,-326],[312,-249],[220,-328],[546,-145],[172,-116],[188,40],[589,-319],[533,4],[150,-69],[177,114],[391,-104],[311,48],[-36,-494],[42,-213],[285,-137],[111,-239],[255,4],[403,269],[364,25],[229,77],[276,-106],[351,235],[524,120],[440,49],[180,-47],[215,94],[202,-76],[188,60],[308,-31],[271,175],[339,108],[331,-15],[256,229],[51,175],[345,72],[300,228],[352,-52],[263,217],[270,496],[355,103],[54,93],[370,-19],[296,149],[229,343],[287,274],[-13,182],[253,461],[478,133],[195,-40],[585,128],[460,309],[295,363],[197,158],[-22,223],[373,459],[182,140],[263,466],[-261,372],[63,336],[102,188],[-112,641],[12,356],[201,221],[39,266],[170,245],[121,467],[22,484],[-117,141],[-43,356],[46,468],[191,422],[-64,110]],[[80515,42287],[-130,77],[-45,-262],[261,-15],[240,-152],[123,32],[106,-272],[144,-75],[-18,-132],[273,-130],[244,-27],[62,-170],[186,-89],[310,-292],[86,75],[174,-138],[258,28],[151,-83],[117,-273],[275,-409],[184,-156],[384,-42],[118,-195],[536,-116],[208,-147],[107,38],[175,-145],[245,-379],[16,-120]],[[91160,43858],[-270,-183],[-291,-304],[-15,-101],[-442,-280],[-72,87],[-92,-201],[-838,-704],[-158,112],[-345,70],[-428,-81],[-130,323],[-420,559],[-273,99],[-245,163],[-401,136],[-408,201],[-317,-755],[-259,-96],[-184,45],[-307,-44],[-167,240],[-459,273],[-260,301],[-299,-11],[-435,-146],[-197,47],[-214,183],[-249,-173],[-731,-316],[-127,-129],[-263,117],[-230,-194],[-69,-206],[-231,-80],[-61,-126],[-551,-226],[-207,-171]],[[85305,38718],[198,-128],[286,-303],[310,51],[35,176],[263,240],[288,150],[401,18],[322,69],[-16,187],[413,8],[372,389],[372,581],[196,68],[27,147],[333,622],[588,535],[666,687],[312,177],[476,542],[171,-133],[2,249],[343,446],[74,259],[-266,14],[-90,-123],[-237,14],[16,198]],[[84732,38720],[160,-320],[-224,-227],[-88,-635],[-109,-142],[128,-289],[184,-22],[-122,-157],[138,-345],[-11,-301],[-225,-301],[-194,-101],[-391,-419],[-208,171],[-301,-227],[-237,-53],[-96,-325],[-251,-98],[135,-253],[-183,-296],[15,-165],[-149,-71],[-102,-308],[-254,-449],[50,-269],[-355,-348],[16,-281],[-472,-456],[-271,260],[-497,222],[-492,-8]],[[85305,38718],[-152,-168],[-448,325],[27,-155]],[[94799,30553],[171,-129],[322,88],[248,297],[33,144],[497,689],[162,66],[281,825],[713,-100],[-90,637],[2,374],[-124,346],[-266,130],[-158,428],[-152,151],[50,431],[-111,565],[136,394],[-58,334],[55,121],[551,-225],[231,26],[156,-115],[54,-202],[294,-6],[520,-123],[216,85],[564,-127],[249,152],[485,174],[169,1000],[-185,387],[90,545],[-11,211],[-353,228],[-57,194],[-26,1191],[163,275],[-181,308],[-312,260],[-84,324],[-3,546],[186,252],[-105,253],[-158,162],[-34,172],[126,111],[149,-33],[210,492],[80,620],[-143,121],[27,378],[-281,-41],[-382,251],[-479,-64],[-210,-162],[-154,12],[-102,229],[-195,123],[-212,23],[-443,-474],[-143,-52],[-276,-258],[-275,-98],[-80,590],[-263,613],[-340,80],[-218,148],[-318,549],[-415,236],[-438,-223],[-14,-152],[-226,-156],[-1646,-253],[-165,-206],[-636,-515],[-307,-322]],[[80515,42287],[-485,415],[-92,181],[-563,535],[-414,336]],[[80326,32507],[159,237],[-5,201],[329,325],[86,244],[-108,796],[-299,126],[-25,147],[158,427],[-167,147],[-314,20],[-54,275],[-198,51],[-120,203],[-339,244],[-236,-16],[-15,101],[-314,312],[-42,-98],[-163,202],[353,182],[658,226],[540,371],[6,685],[192,540],[396,580],[212,44],[237,-76],[166,127],[308,-32],[241,-205],[370,-106],[191,-114],[252,-41],[49,190],[-138,327],[656,-88],[491,-102],[493,-13],[314,-112],[86,-114]],[[25983,22396],[24,-246],[212,-291],[29,-406],[303,-410],[317,618],[1,310],[237,346],[215,47],[190,153],[182,-367],[42,-303],[129,-242],[255,-292],[111,-299],[336,-148],[164,262],[71,431],[-46,176],[177,236],[201,-48],[374,58],[39,247],[-150,188],[162,88],[81,-120],[294,516],[151,413],[250,332],[395,-64],[278,593],[250,156],[357,397],[78,-33],[189,247],[-69,266],[369,144],[225,174],[-7,203],[224,250],[-12,141],[182,-190],[399,286],[-22,148],[810,171],[365,192],[-31,-335],[56,-489],[159,-263],[-100,-184],[553,-212],[215,62],[35,281],[109,132],[81,380],[239,460]],[[27226,24790],[-155,-306],[-161,-80],[-28,-206],[-152,-317],[-297,-484],[-27,-262],[-423,-739]],[[32124,32313],[-682,-674],[-252,-104],[5,-104],[-236,-291],[-72,-451],[-122,279],[31,318],[-203,149],[-143,214],[25,253],[-324,364],[-328,29],[-396,-90],[-272,-8],[-410,71],[-133,-70],[405,-793],[132,-463],[-301,-403],[-278,-90],[-457,-17],[-51,-603],[-24,-861],[362,-308],[20,-239],[-125,-669],[-88,-874],[370,-840],[-519,-263],[-282,-771],[-286,-154],[-264,-60]],[[32794,12017],[-83,-446],[-163,-533],[-71,-83],[-102,-569],[-377,-412]],[[39222,16726],[-498,-296],[-246,-104],[-250,5],[-403,-317],[-187,-4],[53,124],[-242,218],[-405,-208],[-653,262],[-229,33],[8,-254],[-381,-148],[-8,-188],[-264,-37],[-117,-161],[-417,-257],[-151,126],[-81,-93],[-637,-293],[264,-380],[101,-26],[39,-321],[217,76],[20,-202],[-92,-621],[-283,86],[155,-360],[-407,-59],[-151,78],[-313,-287],[-459,-920],[-256,-164],[-155,-17]],[[32445,3783],[151,251],[235,117],[265,392],[433,346],[101,-221],[209,190],[279,80],[181,157],[216,20],[120,138],[500,84],[168,-44],[204,176],[175,266],[331,104],[239,-282],[755,-6],[303,-216],[-5,-277],[197,-173],[95,161],[386,6],[227,338],[-2,203],[387,161],[127,-110],[203,-491],[33,-649],[109,-178],[225,-40],[274,164],[274,-209],[215,60],[217,278],[81,250],[354,33],[509,-123],[391,-28],[143,100],[526,144],[99,74],[-34,230],[171,384],[885,480],[-524,493],[-201,11],[-631,317],[-333,287],[362,945],[262,64],[58,117],[316,43],[456,-7],[205,152]],[[31998,9974],[146,-263],[-7,-407],[271,-410],[192,14],[-153,-705],[57,-396],[-110,-230],[-261,-336],[-161,-115],[179,-323],[114,-457],[221,-126],[336,62],[30,-239],[176,-100],[-150,-180],[-356,-150],[-228,63],[-218,-189],[-177,-33],[85,-326],[-45,-264],[239,-262],[52,-308],[215,-511]],[[36518,20413],[-120,-154],[-385,-282],[-303,-150],[-88,-170],[-293,50],[-330,-94],[-330,-222],[-352,76],[-140,202],[-10,163],[-1057,366],[-205,28],[-439,-106],[-298,-133],[-144,-300],[-238,-340],[-55,-184],[-293,-314],[-5,-436],[-132,-345],[-257,-303],[-100,38],[-107,-315],[-35,-947],[-121,-376]],[[30681,16165],[732,-441],[71,-308],[104,-161],[115,-830],[214,-149],[82,-314],[344,-415],[31,-265],[159,-318],[207,-606],[54,-341]],[[25983,22396],[-217,-552],[77,-281],[-35,-138],[201,-533],[-20,-95],[458,-599],[244,-179],[392,-98],[88,-110],[257,-42],[167,191],[304,-311],[419,-256],[466,0],[107,-543],[264,-748],[-86,-129],[77,-165],[-48,-244],[157,-20],[-14,-564],[263,-192],[77,-206],[36,-396],[227,-82],[837,61]],[[27139,9895],[-108,-116],[-575,-133],[-571,62],[-233,-43],[-114,112],[-957,112],[-337,100],[-315,-401],[-232,-60],[-256,103],[-616,-190],[-232,-238],[-365,-164],[-106,-121],[-296,-94],[-290,-12]],[[27886,4768],[-30,780],[-293,265],[-91,182],[88,156],[-6,387],[177,489],[20,211],[-169,223],[-240,79],[-214,280],[39,253],[-62,237],[192,906],[-55,455],[-103,224]],[[21536,8812],[-89,-230],[-97,-537],[53,-530],[-207,-251],[-51,-315],[-334,-760],[-227,-446],[-79,-586],[632,-20],[124,85],[169,-93],[-71,-509],[137,-95],[98,-484],[337,-573],[212,29],[423,287],[110,-259],[-104,-310],[-481,-163],[242,-881],[-82,-1897],[693,-274],[309,74],[246,-12],[332,85],[239,219],[118,-25],[177,160],[275,462],[226,227],[-100,143],[-56,397],[44,337],[98,177],[-131,520],[123,349],[1632,731],[157,139],[315,-156],[226,87],[712,854]],[[27886,4768],[157,-420],[-16,-753],[-148,-320],[-126,-116],[112,-304],[-138,-352],[149,-353],[318,-455],[701,79],[337,167],[409,57],[573,307],[244,91],[252,-29],[256,233],[255,358],[297,75],[90,128],[300,155],[276,357],[120,-29],[141,139]],[[31998,9974],[-179,-3],[-345,131],[-496,701],[-232,216],[-365,26],[-271,-94],[-396,144],[-345,363],[-176,394],[-324,-28],[-416,261],[-339,148],[-598,-69],[-344,-528],[-67,-464],[-304,-36],[18,-616],[129,-351],[191,-274]],[[27226,24790],[-552,198],[-436,261],[-145,33],[-642,-750],[-288,-480],[-178,-397],[-333,-512],[-359,-346],[-371,-247],[-415,-194],[-215,-43],[3,-731],[118,-95],[441,-772],[-82,-416],[135,-275],[66,-775],[76,-145],[-14,-381],[-102,-285],[86,-144],[-131,-363],[-7,-293],[-97,-84],[13,-309],[-170,-245],[-72,-246],[-315,-176],[-240,-47],[107,-80],[103,-269],[11,-325],[-762,-109],[51,-924],[146,-497],[223,-579],[-125,-411],[-2,-335],[-160,-142],[376,-348],[-402,-224],[66,-213],[-120,-510],[-164,-222],[-597,-244],[-562,-26],[-236,156],[-352,-18],[-154,-528],[17,-144],[400,-443],[77,-323],[203,-384],[173,-81],[26,-191],[193,-305]],[[30866,45126],[-331,88],[-46,190],[-169,37],[56,142],[-134,229],[106,274],[-181,135],[-687,-672],[-96,376],[-217,-428],[46,-342],[-164,196],[76,90],[-97,155],[-780,-386],[-505,210],[-222,-54]],[[34071,35534],[-250,-99],[-197,48],[-233,-183],[-275,319],[46,56],[-272,115],[80,285],[-10,368],[92,190],[7,275],[268,807],[-84,451],[-249,173],[-365,23],[-386,-132],[81,189],[-65,335],[128,487],[-222,760],[-178,83],[-263,271],[-135,0],[43,203],[258,221],[-204,305],[-819,1018],[137,284],[337,416],[107,383],[-565,132],[-23,228],[169,20],[-100,172],[137,242],[-118,488],[23,468],[-105,191]],[[27521,45366],[-89,-232],[150,-312],[-210,-183],[-21,-224],[-278,-173],[-68,-188],[-253,-199],[-52,-127],[163,-67],[8,-305],[171,-274],[181,-33],[300,-584],[-25,-550],[72,-369],[-74,-425],[-198,-334],[-202,-489],[-23,-688],[33,-314],[100,-283],[259,-359],[323,-314],[127,90],[703,-109],[446,-37],[358,-207],[476,-31],[507,-198],[69,-359],[-97,-358],[-178,-264],[-32,-321],[898,-98],[161,121],[144,-414],[236,-231],[339,-47],[185,56],[206,-248],[-270,-238],[114,-414],[-306,-333],[224,-503]],[[33704,47477],[23,-241],[-261,-184],[146,23],[197,-318],[-30,-220],[-206,-315],[-163,-139],[-367,-70],[-221,-182],[-333,-28],[-415,-248],[-179,-361],[-155,-20],[-362,-210],[-231,-73],[-281,235]],[[35377,44918],[-144,102],[-566,48],[-384,254],[-449,709],[-1,91],[338,550],[-42,158],[9,489],[-178,203],[-256,-45]],[[36813,40363],[59,318],[-5,498],[-69,158],[-263,178],[-175,572],[-186,301],[30,130],[-197,115],[-253,583],[-2,428],[-72,360],[-133,190],[-22,266],[-210,291],[62,167]],[[36776,37102],[-31,284],[-121,267],[13,195],[-91,353],[-165,184],[59,481],[-270,395],[116,263],[-42,616],[157,-45],[265,88],[147,180]],[[31032,52660],[-96,-241],[-206,-186],[-174,-366],[-147,-168],[-130,44],[-129,-134],[-328,-165],[-112,-122],[-249,289],[-238,-128],[-239,41],[-227,320],[173,200],[131,-58],[179,139],[-191,190],[-425,195],[-219,-92],[25,163],[-327,-150],[-32,-506],[-165,-58],[-459,-288],[250,-202],[88,-290],[357,-284],[289,-116],[344,-252],[55,-182],[347,-358],[81,-207],[-53,-307],[-296,-174],[-329,-114],[43,-479],[-124,-474],[76,-218],[-172,-96],[-450,-569],[-150,-636],[-29,-273],[-168,-318],[-203,-263],[118,-401]],[[33704,47477],[-267,91],[-113,304],[159,522],[267,338],[-106,288],[-213,213],[-49,189],[-236,90],[33,156],[-158,116],[-403,-215],[-30,291],[-279,121],[-197,-190],[-191,326],[115,139],[-26,219],[201,17],[345,229],[26,423],[405,483]],[[41161,51650],[272,0],[-17,157],[155,131],[22,259],[75,-145],[184,103],[193,352],[518,404],[214,116]],[[40188,52013],[267,47],[421,-235],[84,-125],[201,-50]],[[39193,54297],[345,-20],[-109,-311],[197,-92],[-92,-400],[187,-53],[-124,-806],[469,-111],[122,-491]],[[38479,56074],[154,-495],[197,-310],[63,-326],[-138,-480],[121,-185],[234,145],[83,-126]],[[39030,58710],[-337,-273],[311,-143],[-228,-368],[161,-183],[-282,-229],[333,-438],[-400,-350],[158,-135],[-255,-359],[-12,-158]],[[41563,46771],[-383,-2],[-8,-72],[-358,40],[-181,-106],[-142,105],[-179,-58],[-117,213],[-332,-140]],[[41600,46446],[-37,325]],[[41210,45158],[50,494],[46,-4],[249,515],[45,283]],[[40974,44886],[119,356],[117,-84]],[[39396,44428],[276,-5],[542,-205],[138,205],[165,-53],[90,163],[141,-52],[85,438],[141,-33]],[[39863,46751],[-740,-203],[-179,25],[-552,-579],[308,-324],[48,-290],[418,-498],[209,-117],[-77,-109],[98,-228]],[[41161,51650],[99,-291],[-42,-237],[173,-97],[168,-396],[196,-138],[88,-200],[-392,-59],[144,-198],[437,-323],[309,43],[136,-50],[-50,-154],[89,-233],[171,-1],[300,207],[426,14],[235,-46],[118,213]],[[43229,44811],[-201,9],[-399,-110],[-528,-50],[-244,170],[-44,142],[-389,79],[-214,107]],[[43135,43223],[110,71],[5,211],[-225,123],[119,160],[-22,348],[107,675]],[[41142,44006],[276,-315],[15,204],[277,4],[111,-120],[-96,-446],[86,-152],[-3,-287],[-87,-65],[194,-240],[464,391],[37,203],[141,-61],[162,231],[183,8],[233,-138]],[[40974,44886],[-78,-580],[214,-122],[32,-178]],[[44006,47253],[161,0]],[[43858,49459],[-165,-68],[-65,-466],[67,-227],[-4,-587],[111,46],[11,-230],[224,-546],[-31,-128]],[[40569,49955],[14,230],[-97,202],[-99,-57],[-284,567]],[[38757,50164],[142,-214],[92,110],[256,-63],[226,94],[247,-320],[101,-45],[534,117],[214,112]],[[38776,50702],[-92,-223],[73,-315]],[[40103,50897],[-427,-92],[-27,188],[-529,-325],[-113,201],[-231,-167]],[[36779,56766],[355,-60],[110,157],[59,-106],[269,-107],[307,-12],[-27,-76],[481,-293],[-27,-147],[173,-48]],[[43658,45743],[-353,1186],[399,194],[38,-78],[264,208]],[[43433,45586],[225,157]],[[41600,46446],[208,-165],[330,9],[379,197],[29,-151],[267,-135],[60,-212],[371,22],[205,-216],[-16,-209]],[[40761,49496],[164,-9],[202,-740],[129,24],[65,-533],[130,-573],[83,-201],[18,-311],[-121,-20],[132,-362]],[[40569,49955],[192,-459]],[[40188,52013],[-92,-20],[141,-950],[-134,-146]],[[38777,53136],[-280,33],[-8,-117],[-222,153],[21,147],[-242,-15],[-58,195],[-436,-437],[-321,-171],[-164,23],[-50,203],[-206,-134],[-247,68],[71,-394],[-240,-152],[-150,-328],[-336,-52],[-101,-179],[-337,-179]],[[38647,51222],[136,33],[152,308],[-69,572],[-187,162],[185,309],[6,439],[-93,91]],[[35397,51748],[126,-142],[292,16],[171,-111],[145,-388],[487,136],[548,-108],[146,225],[237,-284],[175,-54],[225,131],[26,-94],[404,183],[-28,256],[167,66],[129,-358]],[[39863,46751],[-330,407],[92,288],[-67,198],[177,104],[-124,100],[-84,376],[45,131],[-72,451],[52,100],[375,75],[140,167],[554,83],[-56,190],[196,75]],[[38372,39933],[64,183],[-84,272],[105,20],[-192,262],[33,226],[-59,346],[-283,307],[-86,181],[-425,538],[-104,396],[151,213],[372,307],[210,381],[262,62],[258,-59],[398,87],[108,463],[296,310]],[[37721,39252],[313,260],[282,412],[56,9]],[[36813,40363],[33,-392],[195,-20],[101,158],[579,-857]],[[38757,50164],[-122,-105],[-211,18],[-126,-261],[-350,-366],[395,-740],[53,-551],[-248,-87],[-60,-235],[-380,191],[139,94],[-159,98],[-241,-171],[-345,135],[-293,-109],[48,-133],[-529,52],[-327,-128],[-178,91],[-169,-169],[28,-203],[167,-91],[-154,-79],[72,-278],[-195,-34],[165,-92],[113,-205],[-629,-425],[104,-191],[327,-208],[217,-458],[-34,-326],[-239,-338],[-219,58]],[[38776,50702],[-129,520]],[[37445,37267],[10,355],[75,279],[-221,360],[-304,41],[211,238],[200,464],[305,248]],[[43229,44811],[85,148],[-72,136],[191,491]],[[39193,54297],[-329,-441],[-87,-720]],[[45908,45134],[-241,533],[-320,344],[-252,163]],[[43658,45743],[247,-312],[235,18],[288,-260],[328,-97],[165,154],[216,-13],[13,-139],[293,-76],[465,116]],[[41176,41991],[-253,501],[38,358],[-20,583],[201,573]],[[38372,39933],[303,248],[125,31],[357,398],[652,252],[372,95],[218,132],[339,302],[438,600]],[[56688,58099],[-202,-272],[-276,-64],[-189,-240],[223,-300],[72,-532],[235,-303],[-90,-103],[3,-301],[69,-10],[-72,-607],[-171,-406],[-319,-221],[-55,92],[-394,-214],[-291,13]],[[59024,57002],[-270,138],[15,257],[-402,254],[-164,214],[28,125],[-185,180],[-95,-244],[-248,79],[-150,-218],[-314,-16],[18,131],[-260,183],[-23,290],[-286,-276]],[[62013,55446],[-196,-173],[-281,-100],[-1,-157],[-137,-245],[-748,76],[-218,-56],[-210,58],[-128,210],[-207,53],[-300,418],[39,469],[-67,492],[-473,274],[-62,237]],[[62358,54911],[-162,47],[-66,356],[-117,132]],[[63082,51171],[-141,314],[42,349],[-66,467],[135,557],[-303,189],[-28,321],[-440,184],[33,553],[-107,369],[27,258],[124,179]],[[59846,47712],[34,154],[276,251],[408,180],[110,179],[279,179],[288,10],[-50,253],[119,312],[397,464],[219,407],[145,41],[243,375],[208,140],[201,317],[-25,69],[239,150],[145,-22]],[[55231,54631],[-123,-393],[153,-320],[81,27],[-53,-293],[137,90],[266,-50],[257,-164],[248,-41],[-67,-382],[89,-116],[170,109],[185,-150],[440,-18],[158,195],[99,-240],[-133,-272],[-105,-15],[-17,-648],[178,-119],[5,-201],[247,-203],[-56,-269],[79,-616],[179,-69],[218,-530],[24,-307],[162,-248],[441,-267],[243,-349],[96,-6],[236,-298],[-87,-35],[174,-419],[-147,-211],[179,-29],[73,-268],[260,71],[192,-47],[134,182]],[[58519,65588],[-51,-851],[-87,-319],[-166,-242],[-45,-213],[-174,-256],[-204,-116],[-55,-363],[-317,-406],[-187,-604],[-200,-126],[-148,-283],[-212,-243],[-717,-524],[-386,247]],[[59848,66133],[-253,141],[-332,-157],[-196,-177],[-193,-6],[-355,-346]],[[63028,65894],[-121,75],[-368,-29],[-177,115],[-389,-18],[-325,171],[-300,-100],[-323,75],[-149,123],[-765,105],[-263,-278]],[[61722,59861],[135,184],[-223,312],[35,176],[-361,236],[-96,275],[-170,211],[-40,378],[181,461],[-92,303],[54,170],[-24,499],[95,379],[-3,230],[136,348],[250,446],[-133,174],[88,68],[289,-71],[453,257],[171,179],[292,-202],[152,116],[-40,213],[153,245],[4,446]],[[59024,57002],[316,486],[211,201],[217,17],[95,134],[44,483],[-24,377],[165,-89],[223,12],[83,345],[103,118],[186,-19],[413,102],[207,108],[47,242],[164,283],[248,59]],[[55570,61289],[144,-328],[125,-55],[94,-263],[209,-260],[295,-131],[-32,-216],[-220,38],[-268,-182],[-228,-296],[405,-147],[124,101],[136,-209],[231,-610],[-19,-100],[122,-532]],[[52243,59484],[126,106],[748,384],[397,-122],[154,181],[449,-46],[202,87],[153,-199],[195,-82],[120,-308],[128,236],[253,297],[143,597],[138,248],[121,426]],[[57171,65375],[74,-116],[-300,-319],[-10,-284],[207,-311],[-624,-520],[-611,-230],[-617,48],[-272,-85],[-127,137],[-514,-237],[-126,195],[33,-326],[-74,-239],[-363,-403],[106,-90],[-199,-245],[-319,-269],[-112,-289],[-418,148],[-150,-116],[-237,81]],[[58519,65588],[-180,54],[-98,-112],[-119,102],[-128,-144],[-232,121],[-16,-103],[-286,106],[-289,-237]],[[55976,48275],[297,-189],[-82,-392],[384,-534],[302,-55],[291,-460],[109,-22]],[[54376,49124],[118,-83],[301,102],[149,204],[185,-62],[30,-219],[321,-149],[354,46],[133,-283],[9,-405]],[[53043,50088],[141,-82],[283,76],[137,-132],[187,-340],[466,137],[333,-40],[76,-264],[-146,-256],[-144,-63]],[[55231,54631],[-496,361],[-238,78],[-149,223]],[[60311,47037],[-209,594],[-256,81]],[[57277,46623],[421,48],[104,79],[700,185],[538,-42],[206,116],[686,-124],[379,152]],[[51469,64373],[106,-227],[224,-7],[-136,-397],[-219,-315]],[[56390,65699],[-106,-2],[-26,-227],[-111,15],[-316,-187],[-169,-238],[181,-132],[-303,-301],[-208,-18],[-137,238],[-232,-159],[0,257],[-97,-78],[-185,249],[-242,130],[-335,-89],[-192,580],[-85,98],[-622,-113],[-649,40],[-603,155],[-83,-185],[221,-193],[-325,-205],[-252,32],[-141,-244]],[[57171,65375],[-80,-86],[-262,-13],[-122,144],[-116,-103],[-141,127],[-60,255]],[[60311,47037],[288,115],[247,-59],[237,196],[14,-330],[160,-248],[361,-106],[25,-115],[220,-169],[-103,-147],[270,-97],[113,-249],[139,-73],[257,-296],[389,-329]],[[68365,46010],[21,152],[-451,926],[-318,269],[-818,825],[-403,345],[-1136,734],[-555,334],[-1163,589],[-277,542],[-143,121],[-40,324]],[[62358,54911],[247,130],[207,-4],[221,122],[81,177],[148,10],[20,326],[332,588],[192,69],[-124,166],[176,215],[27,304],[-192,426],[-298,1],[-161,190],[-362,176],[121,213],[95,396],[132,328],[266,304],[1040,507],[246,214],[306,-26],[127,-120],[222,-42],[287,41],[171,154],[347,707],[48,483],[272,159],[191,-14],[160,230],[40,315],[-52,209],[66,150],[-66,318],[287,374],[246,35],[328,306],[-96,916],[531,404],[-17,167],[-169,428],[34,96],[-108,349],[-2,216],[227,248],[118,533],[140,140],[-386,353],[-40,-119],[-619,-119],[-429,-44],[-366,274],[-113,324],[-192,17],[-360,-203],[-193,5],[-363,-171],[-344,-62]],[[61722,59861],[150,-167],[263,-48],[25,-113],[-169,-148],[-2,-201],[668,-126],[141,-272],[-191,-112],[-34,-394],[-71,-179],[44,-390],[-242,83],[-109,-308],[-87,51],[252,-583],[219,-100],[-297,-443],[-102,188],[-131,30],[-112,-227],[82,-158],[-77,-175],[42,-297],[-136,-153],[165,-173]],[[65005,66800],[-248,-246],[-635,147],[-375,-232],[-181,134],[-228,-92],[-163,-463],[-147,-154]],[[44082,40857],[104,-246],[-162,-122],[122,-126],[-125,-230]],[[45318,40157],[-72,-260],[-221,-142],[-350,420],[-493,819],[-100,-137]],[[46709,38500],[-218,469],[-266,91],[-196,325],[-367,146],[-289,308],[-55,318]],[[42266,41482],[-222,-148],[-328,431],[-242,-71],[-241,149],[-57,148]],[[41701,40049],[14,109],[219,199],[-161,183],[71,79],[313,36],[197,333],[-101,42],[90,163],[-130,164],[53,125]],[[39519,37160],[-170,342],[160,237],[-301,196],[288,239],[273,-3],[294,555],[365,172],[123,-10],[310,390],[77,221],[255,242],[508,308]],[[51054,46746],[253,55],[337,-58],[215,159],[225,43],[-75,224],[202,38],[417,514],[159,-74],[273,11],[39,-257],[240,163],[405,-6],[364,-149]],[[48817,47243],[177,-34],[386,86],[418,-157],[117,123],[311,91],[27,-114],[237,-203],[325,24],[239,-313]],[[54108,47409],[175,153],[-41,168],[-439,401],[61,129],[-203,23],[-143,182],[-2,266],[180,41],[326,244],[354,108]],[[54425,44605],[177,-76],[300,137],[728,159],[368,169],[38,154],[185,-45],[309,109],[172,-69],[293,38],[284,-239],[255,113],[1039,195],[220,-33],[361,120],[183,-110],[105,54],[474,-185],[199,56],[304,-130],[36,-124],[263,-293],[127,-2],[293,-243],[243,-277],[62,-233],[-225,-45],[-318,-187],[-153,-305],[-253,-299],[-288,-231],[-127,-233]],[[54177,44732],[248,-127]],[[57277,46623],[-196,-157],[-237,219],[-154,-114],[11,-222],[-273,-292],[-430,-10],[-275,-76],[-249,57],[-209,-138],[-97,114],[-40,-167],[-261,11],[-147,-175],[-82,-637],[-154,-52],[-307,-252]],[[51198,45346],[-113,166],[-72,299],[175,254],[-237,225],[-49,193],[152,263]],[[50482,45112],[279,33],[-12,153],[165,84],[284,-36]],[[47735,46613],[152,115],[89,-326],[567,-389],[345,-304],[193,176],[403,-305],[287,104],[12,146],[427,69],[156,-33],[8,-174],[212,179],[84,-225],[-187,-32],[-220,-193],[-372,-114],[-446,-303],[-20,-182],[340,30],[502,215],[215,45]],[[47444,47128],[136,-312],[155,-203]],[[53114,41298],[-224,331],[-333,281],[-104,329],[29,268],[-174,151]],[[51595,40918],[299,11],[434,457],[195,4],[377,-354],[214,262]],[[51073,41004],[418,-44],[0,-205],[104,163]],[[49514,41727],[327,-57],[18,-249],[237,-39],[40,-248],[276,-169],[160,-1],[186,220],[211,60],[104,-240]],[[51835,42701],[-149,-178],[-586,6],[-337,-124],[-264,56],[-62,-71],[-441,-158],[-269,-148],[-197,-194],[-16,-163]],[[52308,42658],[-243,159],[-230,-116]],[[45908,45134],[580,-1501]],[[46526,43559],[399,290],[204,80],[-133,167],[82,218],[-106,50],[-245,533],[-49,515],[77,214],[0,635],[164,399],[270,39],[160,-101],[-12,-313],[437,212],[-39,116]],[[46488,43633],[38,-74]],[[49514,41727],[-148,-80],[-162,-248],[-483,53],[-168,-137],[61,-116]],[[49982,39970],[136,33],[347,284],[167,73],[34,209],[407,435]],[[48614,41199],[378,-328],[383,-114],[171,-427],[436,-360]],[[50723,43430],[418,-212],[-14,-95],[495,-7],[213,-415]],[[50482,45112],[-1,-95],[-324,-256],[-546,-111],[-2,-101],[273,7],[63,-310],[223,-47],[144,-331],[158,74],[91,-450],[162,-62]],[[52067,45258],[-163,100],[-230,0],[-197,89],[-279,-101]],[[52677,43657],[-93,306],[-233,513],[-76,316],[-208,466]],[[52308,42658],[-13,328],[106,-12],[-12,272],[288,411]],[[54425,44605],[-114,-224],[133,-448]],[[54444,43933],[214,-42],[137,148],[494,-173],[99,42],[320,-247],[172,-17],[157,249],[507,-184],[134,-202],[510,-205],[478,-270],[200,69],[92,-189],[5,-340],[124,111],[408,-465],[168,215],[318,111],[-26,-779],[293,-192]],[[53269,45330],[-168,-15],[-348,191],[-379,-42],[-307,-206]],[[54149,44733],[-145,189],[-246,43],[-264,283],[-225,82]],[[52677,43657],[175,113],[30,198],[545,216],[137,395],[359,-88],[226,242]],[[51800,38269],[62,100],[-203,171],[-76,349],[56,66],[-189,519],[68,375],[97,78],[-82,164],[111,106],[-60,140],[124,334],[-113,247]],[[49982,39970],[122,-181],[326,-118],[226,-333],[308,54],[342,-321],[176,-259],[218,-487],[100,-56]],[[54149,44733],[28,-1]],[[54106,47370],[-167,-458],[-335,-537],[-111,-475],[-5,-243],[-195,-197],[-24,-130]],[[55976,48275],[-186,-101],[-292,-281],[-392,-13],[-419,218],[-141,-239],[43,-107],[-122,-232],[-361,-150]],[[42504,39322],[-446,322],[-357,405]],[[51800,38269],[344,-198],[120,13],[317,-271],[134,97],[815,-287],[217,-134],[265,-67],[421,-489],[281,-227],[164,-536],[244,-33],[77,-130],[-11,-260],[84,-265],[151,-186],[9,-266],[344,-228],[268,-44]],[[54444,43933],[-519,-158],[-200,-277],[-29,-276],[-135,-214],[64,-521],[-309,-377],[-30,-379],[60,-249],[-86,-160],[-146,-24]],[[46526,43559],[371,-485],[171,-332],[504,-17],[121,200],[150,80],[106,-174],[378,92],[338,276],[439,-189],[246,125],[194,-163],[229,196],[172,-180],[373,61],[280,209],[125,172]],[[45732,42789],[-124,206],[-165,60],[-182,-134],[-68,104],[-349,-100],[33,-113],[-225,18],[-4,-162],[-253,-187],[-360,84],[-57,-113],[-153,170],[-565,112],[-100,59]],[[45318,40157],[-4,426],[75,297],[240,1313],[-51,117],[154,479]],[[42447,41813],[246,-273],[158,124],[86,-147],[182,72],[152,-96],[170,-241],[253,-512],[388,117]],[[43160,42793],[-128,-108],[40,-207],[-172,-394],[-205,-77],[-248,-194]],[[47753,38825],[171,41],[114,513],[-55,370],[72,9],[14,455],[216,404],[-322,-40],[430,511],[221,111]],[[46488,43633],[-229,-123],[-253,-265],[-117,57],[-157,-513]],[[42447,41813],[-181,-331]],[[43135,43223],[-108,-236],[133,-194]],[[54106,47370],[2,39]],[[54190,71379],[289,157],[299,-138],[141,-174],[369,-57],[11,243],[196,148],[39,-208],[387,573],[279,106],[418,349],[106,-35]],[[52868,72655],[95,54],[471,-42],[-5,-263],[-127,-68],[-46,-190],[159,-387],[-45,-205],[328,-111],[347,7],[145,-71]],[[54628,74680],[-90,-13]],[[56724,72343],[-617,375],[-83,110],[134,128],[177,-158],[20,198],[-246,275],[-629,124],[-45,85],[180,577],[-45,134],[-174,-143],[-204,31],[-9,608],[-555,-7]],[[57772,75775],[-433,-251],[92,-117],[-404,-58],[-126,-387],[-419,-265],[-138,128],[-193,386],[20,186],[-674,-94],[-237,-293],[-75,187],[-246,65],[-311,-582]],[[59277,75446],[-122,180]],[[58410,72208],[149,111],[238,319],[305,259],[-403,256],[83,207],[-22,275],[-128,203],[26,576],[177,-22],[227,99],[95,-50],[-114,390],[11,187],[222,288],[1,140]],[[56724,72343],[232,121],[198,-62],[240,-193],[237,133],[244,25],[418,-226],[117,67]],[[61390,75098],[-276,-671],[-205,-96],[188,-616],[-110,-319],[186,-239],[-53,-184],[61,-313],[-251,-801],[7,-232]],[[63626,75011],[-245,-210],[-431,129],[-381,-64],[-254,120],[-518,144],[-271,-138],[-136,106]],[[62963,70753],[-136,289],[45,221],[-132,154],[229,528],[261,297],[-173,70],[52,278],[109,137],[217,477],[-74,183],[137,494],[-103,115],[213,160],[-117,69],[136,248],[72,418],[-73,120]],[[60937,71627],[94,-118],[276,22],[142,-132],[221,-39],[277,76],[147,-133],[95,-257],[180,-105],[278,105],[316,-293]],[[63626,75011],[-163,290],[99,254],[-371,225],[161,376],[-176,152],[-27,211],[121,400],[-426,247],[102,352],[-181,101],[77,469],[332,265]],[[59277,75446],[280,-112],[283,76],[237,-91],[211,9],[178,-136],[84,225],[223,-226],[333,17],[284,-110]],[[56390,65699],[-163,125],[-88,249],[-155,32],[-118,269],[-166,-172],[-192,217],[-214,107],[26,134],[-199,-117],[-109,217],[52,208],[-134,207],[94,119],[-105,110],[-88,315],[-235,109],[-33,217],[90,136]],[[54095,69861],[-217,-171],[-527,341],[155,118],[161,-62],[-91,525],[-76,53],[-504,-140],[4,-216],[-155,-109],[176,-257],[-171,-120],[-14,-196],[-116,-130],[3,-628],[-218,-184],[-212,-320],[-284,-180],[-397,-45],[-443,149],[9,-109],[-494,16],[-116,-402],[-152,82],[-310,-309],[-56,-187]],[[54653,68181],[-145,50],[-254,-89],[-129,-336],[-136,40],[-115,-233],[-124,252],[31,341],[180,309],[21,342],[-113,288],[325,286],[48,192],[-147,238]],[[54095,69861],[167,311],[25,206],[149,168],[-187,55],[-87,236],[-152,-108],[-85,425],[265,225]],[[60937,71627],[-586,-67],[-118,85],[-219,-22],[-231,70],[-141,-184],[-315,-149],[-368,239],[-274,377],[-275,232]],[[65005,66800],[-122,136],[-189,528],[198,339],[25,148],[-234,337],[-130,72],[-93,265],[35,299],[-132,252],[-167,31],[-265,187],[-116,244],[54,191],[-158,344],[-418,24],[-146,372],[-184,184]],[[54653,68181],[320,-54],[100,-95],[494,-38],[109,-269],[119,116],[233,-46],[248,86],[124,-60],[92,222],[278,245],[167,-69],[209,134],[34,137],[233,162],[370,166],[295,18],[90,-238],[175,325],[262,-177],[8,-330],[148,-47],[222,174],[424,-415],[133,-414],[166,-98],[-105,-209],[30,-360],[170,-352],[-169,-170],[216,-392]],[[47671,91962],[-426,-182],[-85,87],[-592,-76],[-224,13],[-64,210],[48,208],[178,215],[-248,186],[96,168],[-148,92],[-59,222],[-542,-105],[-514,-174]],[[47809,91403],[-138,559]],[[47629,89149],[110,131],[-81,442],[256,81],[-81,179],[132,55],[74,293],[-44,425],[-250,-50],[-262,384],[348,101],[-22,213]],[[47134,89066],[63,94],[323,-81],[109,70]],[[45091,92826],[159,-246],[423,-341],[152,-537],[101,-649],[-110,-841],[177,-35],[227,-306],[136,58],[112,-355],[195,49],[278,-298],[58,-225],[135,-34]],[[52412,88930],[-132,-316],[-454,-429]],[[53185,88492],[-298,250],[-475,188]],[[52769,87560],[289,292],[55,286],[224,241]],[[51826,88185],[285,-51],[658,-574]],[[51858,82269],[119,-243],[398,-21]],[[53384,84033],[-130,-160],[-103,105],[-599,-358],[-59,-227],[-128,-131],[-326,-59],[58,-272],[-100,-32],[-85,-323],[-91,-95],[37,-212]],[[53391,82061],[-20,299],[366,243],[-34,338],[215,108],[-200,197],[-154,314],[82,113],[-262,360]],[[52833,81635],[558,426]],[[52375,82005],[138,51],[320,-421]],[[46505,93613],[-1680,-381],[266,-406]],[[47671,91962],[164,-118],[385,196],[-228,98],[-245,455],[-146,21],[-161,644],[-860,-113],[-75,468]],[[52893,86613],[180,-49],[398,125],[178,-39]],[[52769,87560],[142,-188],[-17,-186],[-237,-302],[3,-134],[233,-137]],[[51826,88185],[-592,-540],[-82,-177],[156,-127],[-10,-140],[-181,127],[-251,-146]],[[51901,85217],[164,414],[121,6],[92,181],[283,294],[80,228],[252,273]],[[51259,85318],[329,-171],[313,70]],[[50602,87013],[232,-389],[62,-344],[-165,-73],[423,-477],[22,-316],[83,-96]],[[50866,87182],[-264,-169]],[[53384,84033],[-78,54],[308,96],[268,-12],[177,143],[18,306],[123,451]],[[51048,82135],[143,-92],[220,403],[196,43],[-38,-145],[289,-75]],[[50621,82649],[309,-426],[118,-88]],[[50669,83037],[-48,-388]],[[51901,85217],[138,4],[109,-747],[-99,-57],[63,-265],[-799,-212],[-73,15],[2,-511],[88,-99],[-177,-82],[-225,-334],[-259,108]],[[50734,84859],[136,226],[389,233]],[[49169,86726],[101,-320],[-248,-484],[661,-105],[282,27],[26,-226],[192,-61],[53,-210],[116,9],[38,-184],[150,86],[-14,-194],[208,-205]],[[50602,87013],[-239,-78],[-532,2],[-468,-207],[-194,-4]],[[49455,92457],[1,101],[314,-2],[102,-142],[478,387],[468,-322],[281,-395],[-162,-95],[100,-218],[101,-17],[220,239],[164,-715],[98,-293],[231,-133],[231,-249],[165,-38],[293,314],[260,-658],[240,-385],[146,-145]],[[49068,93796],[-168,-102],[-73,-296],[223,-95],[268,-548],[160,-22],[-149,-190],[126,-86]],[[55836,91474],[-470,64],[-287,-172],[-396,281],[-352,-79],[-503,723],[30,276],[-595,694],[-203,-259],[-182,178],[64,77],[-97,302],[-146,186],[-63,-88],[-163,251],[59,73],[-191,273],[-197,65],[-570,315],[-237,347],[-307,-381],[-578,-252],[-108,118],[-160,-110],[-355,-100],[-157,-149],[-604,-311]],[[50734,84859],[-57,-294],[-129,-117],[-32,-216],[419,-179],[-125,-695],[-124,-118],[-17,-203]],[[48976,91538],[276,-142],[165,-238],[151,-13],[176,-606],[123,76],[377,-432],[233,56],[105,-66],[104,153],[254,117],[569,-241],[383,-369]],[[49455,92457],[-192,-249],[-344,-199],[-74,-305],[131,-166]],[[51892,89833],[226,10],[274,-304],[109,-244],[316,-247]],[[55394,82636],[-683,-345],[-133,47],[-303,-464],[-169,-417],[-363,72],[-178,302],[143,243],[-122,128],[-195,-141]],[[52833,81635],[-175,-396],[-278,-403],[54,-124],[219,14],[116,-203],[286,-307],[281,-744],[291,-266],[294,-84],[-100,-187],[103,-182],[-6,-297],[-123,-235],[43,-297],[175,8],[91,-279],[-81,-155],[199,-239]],[[47809,91403],[426,7],[101,-107],[209,228],[269,140],[162,-133]],[[49068,93796],[-1725,-51],[-396,-37],[-442,-95]],[[50621,82649],[-418,-4],[-312,-71],[-58,73],[-359,-505],[-157,-164],[109,-81],[-141,-324],[85,-586]],[[52375,82005],[-319,-420],[-115,64],[-227,-551],[-628,171],[-302,-107],[-18,314],[282,659]],[[51118,89262],[391,-163],[643,-74],[260,-95]],[[51892,89833],[48,-200],[-202,0],[-302,219],[-181,-61],[-214,-323],[77,-206]],[[50733,89352],[-49,-379],[-98,-2],[52,-555],[118,-200],[-287,-77],[124,-457],[68,21],[179,-279],[-107,-67],[133,-175]],[[51118,89262],[-385,90]],[[50733,89352],[-353,5],[-156,172],[-310,-112],[-380,29],[-200,183],[-670,-267],[-201,34],[-38,-146],[-247,-11],[-303,-118],[-246,28]],[[47134,89066],[129,-472],[275,31],[167,-298],[207,192],[86,-154],[190,191],[84,-138],[328,253],[212,-427],[-296,-203],[116,-221],[464,-212],[-113,-136],[-37,-281],[223,-465]]],"transform":{"scale":[0.005149920076922676,-0.004800048000480004],"translate":[222.50657111390467,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/bl.json b/src/onegov/election_day/static/mapdata/2025/bl.json new file mode 100644 index 0000000000..695dc2cbd4 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/bl.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":2761,"properties":{"id":2761,"name":"Aesch (BL)"},"arcs":[[-1,-2,-3,-4,-5,-6]]},{"type":"Polygon","id":2762,"properties":{"id":2762,"name":"Allschwil"},"arcs":[[-7,-8,-9,-10,-11]]},{"type":"Polygon","id":2763,"properties":{"id":2763,"name":"Arlesheim"},"arcs":[[-12,-13,-14,-15]]},{"type":"Polygon","id":2764,"properties":{"id":2764,"name":"Biel-Benken"},"arcs":[[-16,-17,-18]]},{"type":"Polygon","id":2765,"properties":{"id":2765,"name":"Binningen"},"arcs":[[-19,-20,-21,6]]},{"type":"Polygon","id":2766,"properties":{"id":2766,"name":"Birsfelden"},"arcs":[[-22,-23]]},{"type":"Polygon","id":2767,"properties":{"id":2767,"name":"Bottmingen"},"arcs":[[-24,19,-25,-26]]},{"type":"Polygon","id":2768,"properties":{"id":2768,"name":"Ettingen"},"arcs":[[-27,4,-28,-29,-30]]},{"type":"Polygon","id":2769,"properties":{"id":2769,"name":"Münchenstein"},"arcs":[[-31,-32,12,-33]]},{"type":"Polygon","id":2770,"properties":{"id":2770,"name":"Muttenz"},"arcs":[[-34,13,31,-35,22,-36,-37]]},{"type":"Polygon","id":2771,"properties":{"id":2771,"name":"Oberwil (BL)"},"arcs":[[17,-38,7,20,23,-39,-40]]},{"type":"Polygon","id":2772,"properties":{"id":2772,"name":"Pfeffingen"},"arcs":[[27,3,-41,-42,-43]]},{"type":"Polygon","id":2773,"properties":{"id":2773,"name":"Reinach (BL)"},"arcs":[[-44,38,25,-45,32,11,-46,0]]},{"type":"Polygon","id":2774,"properties":{"id":2774,"name":"Schönenbuch"},"arcs":[[9,-47]]},{"type":"Polygon","id":2775,"properties":{"id":2775,"name":"Therwil"},"arcs":[[5,26,-48,15,39,43]]},{"type":"Polygon","id":2781,"properties":{"id":2781,"name":"Blauen"},"arcs":[[-49,28,-50,-51,-52]]},{"type":"Polygon","id":2782,"properties":{"id":2782,"name":"Brislach"},"arcs":[[-53,-54,-55,-56,-57,-58]]},{"type":"Polygon","id":2783,"properties":{"id":2783,"name":"Burg im Leimental"},"arcs":[[-59,-60]]},{"type":"Polygon","id":2784,"properties":{"id":2784,"name":"Dittingen"},"arcs":[[-61,-62,-63,-64,51]]},{"type":"Polygon","id":2785,"properties":{"id":2785,"name":"Duggingen"},"arcs":[[-65,40,2,-66]]},{"type":"Polygon","id":2786,"properties":{"id":2786,"name":"Grellingen"},"arcs":[[64,-67,55,-68,41]]},{"type":"Polygon","id":2787,"properties":{"id":2787,"name":"Laufen"},"arcs":[[-69,52,-70,-71,-72,-73,61]]},{"type":"Polygon","id":2788,"properties":{"id":2788,"name":"Liesberg"},"arcs":[[-74,-75,71,-76]]},{"type":"Polygon","id":2789,"properties":{"id":2789,"name":"Nenzlingen"},"arcs":[[67,54,-77,49,42]]},{"type":"Polygon","id":2790,"properties":{"id":2790,"name":"Roggenburg"},"arcs":[[-78]]},{"type":"Polygon","id":2791,"properties":{"id":2791,"name":"Röschenz"},"arcs":[[-79,62,72,74,-80,58]]},{"type":"Polygon","id":2792,"properties":{"id":2792,"name":"Wahlen"},"arcs":[[69,57,-81]]},{"type":"Polygon","id":2793,"properties":{"id":2793,"name":"Zwingen"},"arcs":[[50,76,53,68,60]]},{"type":"Polygon","id":2821,"properties":{"id":2821,"name":"Arisdorf"},"arcs":[[-82,-83,-84,-85,-86,-87,-88]]},{"type":"Polygon","id":2822,"properties":{"id":2822,"name":"Augst"},"arcs":[[-89,-90,-91,-92]]},{"type":"Polygon","id":2823,"properties":{"id":2823,"name":"Bubendorf"},"arcs":[[-93,-94,-95,-96,-97,-98,-99,-100,-101]]},{"type":"Polygon","id":2824,"properties":{"id":2824,"name":"Frenkendorf"},"arcs":[[-102,-103,-104,-105]]},{"type":"Polygon","id":2825,"properties":{"id":2825,"name":"Füllinsdorf"},"arcs":[[104,-106,89,-107,81,-108]]},{"type":"Polygon","id":2826,"properties":{"id":2826,"name":"Giebenach"},"arcs":[[106,88,-109,82]]},{"type":"MultiPolygon","id":2827,"properties":{"id":2827,"name":"Hersberg"},"arcs":[[[-110,-111,86,-112,-113,-114]],[[84,-115]]]},{"type":"Polygon","id":2828,"properties":{"id":2828,"name":"Lausen"},"arcs":[[-116,-117,92,-118,109,-119]]},{"type":"Polygon","id":2829,"properties":{"id":2829,"name":"Liestal"},"arcs":[[107,87,110,117,100,-120,-121,101]]},{"type":"Polygon","id":2830,"properties":{"id":2830,"name":"Lupsingen"},"arcs":[[-122,98,-123,-124]]},{"type":"Polygon","id":2831,"properties":{"id":2831,"name":"Pratteln"},"arcs":[[36,-125,90,105,103]]},{"type":"Polygon","id":2832,"properties":{"id":2832,"name":"Ramlinsburg"},"arcs":[[116,-126,-127,-128,93]]},{"type":"Polygon","id":2833,"properties":{"id":2833,"name":"Seltisberg"},"arcs":[[-129,119,99,121]]},{"type":"Polygon","id":2834,"properties":{"id":2834,"name":"Ziefen"},"arcs":[[-130,-131,-132,122,97]]},{"type":"Polygon","id":2841,"properties":{"id":2841,"name":"Anwil"},"arcs":[[-133,-134,-135]]},{"type":"Polygon","id":2842,"properties":{"id":2842,"name":"Böckten"},"arcs":[[-136,-137,-138,-139]]},{"type":"Polygon","id":2843,"properties":{"id":2843,"name":"Buckten"},"arcs":[[-140,-141,-142,-143,-144]]},{"type":"Polygon","id":2844,"properties":{"id":2844,"name":"Buus"},"arcs":[[-145,-146,-147,-148,-149,-150]]},{"type":"Polygon","id":2845,"properties":{"id":2845,"name":"Diepflingen"},"arcs":[[-151,-152,-153]]},{"type":"Polygon","id":2846,"properties":{"id":2846,"name":"Gelterkinden"},"arcs":[[-154,-155,-156,-157,-158,152,-159,136,-160]]},{"type":"Polygon","id":2847,"properties":{"id":2847,"name":"Häfelfingen"},"arcs":[[142,-161,-162,-163,-164,-165]]},{"type":"Polygon","id":2848,"properties":{"id":2848,"name":"Hemmiken"},"arcs":[[-166,-167,-168,146]]},{"type":"Polygon","id":2849,"properties":{"id":2849,"name":"Itingen"},"arcs":[[-169,-170,125,115]]},{"type":"Polygon","id":2850,"properties":{"id":2850,"name":"Känerkinden"},"arcs":[[-171,-172,-173,139]]},{"type":"Polygon","id":2851,"properties":{"id":2851,"name":"Kilchberg (BL)"},"arcs":[[-174,-175,-176,-177]]},{"type":"Polygon","id":2852,"properties":{"id":2852,"name":"Läufelfingen"},"arcs":[[143,164,-178,-179,-180,170]]},{"type":"Polygon","id":2853,"properties":{"id":2853,"name":"Maisprach"},"arcs":[[-181,-182,144]]},{"type":"Polygon","id":2854,"properties":{"id":2854,"name":"Nusshof"},"arcs":[[-183,-184,112,-185]]},{"type":"Polygon","id":2855,"properties":{"id":2855,"name":"Oltingen"},"arcs":[[-186,-187,-188,132]]},{"type":"Polygon","id":2856,"properties":{"id":2856,"name":"Ormalingen"},"arcs":[[-189,147,167,-190,-191,-192,153]]},{"type":"Polygon","id":2857,"properties":{"id":2857,"name":"Rickenbach (BL)"},"arcs":[[135,-193,-194,148,188,159]]},{"type":"Polygon","id":2858,"properties":{"id":2858,"name":"Rothenfluh"},"arcs":[[166,-195,133,-196,189]]},{"type":"Polygon","id":2859,"properties":{"id":2859,"name":"Rümlingen"},"arcs":[[160,141,-197,156,-198]]},{"type":"Polygon","id":2860,"properties":{"id":2860,"name":"Rünenberg"},"arcs":[[176,-199,161,197,155,-200]]},{"type":"Polygon","id":2861,"properties":{"id":2861,"name":"Sissach"},"arcs":[[118,113,183,-201,192,138,-202,-203,168]]},{"type":"Polygon","id":2862,"properties":{"id":2862,"name":"Tecknau"},"arcs":[[199,154,191,-204,173]]},{"type":"Polygon","id":2863,"properties":{"id":2863,"name":"Tenniken"},"arcs":[[-205,-206,-207,-208,-209]]},{"type":"Polygon","id":2864,"properties":{"id":2864,"name":"Thürnen"},"arcs":[[-210,201,137,158,151,204]]},{"type":"Polygon","id":2865,"properties":{"id":2865,"name":"Wenslingen"},"arcs":[[203,190,195,187,-211,174]]},{"type":"Polygon","id":2866,"properties":{"id":2866,"name":"Wintersingen"},"arcs":[[149,193,200,182,-212,180]]},{"type":"Polygon","id":2867,"properties":{"id":2867,"name":"Wittinsburg"},"arcs":[[-213,205,150,157,196,140,172]]},{"type":"Polygon","id":2868,"properties":{"id":2868,"name":"Zeglingen"},"arcs":[[175,210,186,-214,162,198]]},{"type":"Polygon","id":2869,"properties":{"id":2869,"name":"Zunzgen"},"arcs":[[202,209,208,-215,126,169]]},{"type":"Polygon","id":2881,"properties":{"id":2881,"name":"Arboldswil"},"arcs":[[-216,-217,129,96,-218]]},{"type":"Polygon","id":2882,"properties":{"id":2882,"name":"Bennwil"},"arcs":[[-219,-220,-221,-222,-223,-224]]},{"type":"Polygon","id":2883,"properties":{"id":2883,"name":"Bretzwil"},"arcs":[[-225,-226,-227]]},{"type":"Polygon","id":2884,"properties":{"id":2884,"name":"Diegten"},"arcs":[[171,179,-228,223,-229,206,212]]},{"type":"Polygon","id":2885,"properties":{"id":2885,"name":"Eptingen"},"arcs":[[227,178,-230,-231,218]]},{"type":"Polygon","id":2886,"properties":{"id":2886,"name":"Hölstein"},"arcs":[[222,-232,-233,127,214,207,228]]},{"type":"Polygon","id":2887,"properties":{"id":2887,"name":"Lampenberg"},"arcs":[[-234,94,232]]},{"type":"Polygon","id":2888,"properties":{"id":2888,"name":"Langenbruck"},"arcs":[[219,230,-235,-236,-237]]},{"type":"Polygon","id":2889,"properties":{"id":2889,"name":"Lauwil"},"arcs":[[225,-238,-239]]},{"type":"Polygon","id":2890,"properties":{"id":2890,"name":"Liedertswil"},"arcs":[[-240,-241,-242,-243]]},{"type":"Polygon","id":2891,"properties":{"id":2891,"name":"Niederdorf"},"arcs":[[217,95,233,231,221,-244,-245]]},{"type":"Polygon","id":2892,"properties":{"id":2892,"name":"Oberdorf (BL)"},"arcs":[[236,-246,239,-247,243,220]]},{"type":"Polygon","id":2893,"properties":{"id":2893,"name":"Reigoldswil"},"arcs":[[-248,130,216,-249,241,-250,-251,237,224]]},{"type":"Polygon","id":2894,"properties":{"id":2894,"name":"Titterten"},"arcs":[[244,246,242,248,215]]},{"type":"Polygon","id":2895,"properties":{"id":2895,"name":"Waldenburg"},"arcs":[[245,235,-252,249,240]]}]}},"arcs":[[[44292,66386],[-89,-139],[-171,14],[-28,-205],[-215,45],[-35,-284],[-285,24],[20,-699],[-202,44],[7,112],[-291,64],[-69,-122],[0,-495],[-490,-4],[-242,-65],[-7,-565],[-144,13],[-304,-221],[-675,288],[-115,-699],[-466,280],[-178,132],[-83,-261],[-750,-610],[-1103,1450],[-375,445]],[[43846,58473],[406,1343],[165,769],[-307,152],[36,432],[-110,986],[-17,287],[26,336],[114,392],[208,261],[80,238],[69,473],[-4,314],[-117,693],[-103,1237]],[[43589,55267],[257,3206]],[[36804,57028],[880,-323],[221,-137],[205,80],[35,-295],[222,-34],[21,135],[228,-152],[805,42],[399,-427],[108,-206],[238,-281],[127,19],[445,-365],[484,-35],[12,135],[129,-129],[181,-62],[180,8],[106,-141],[64,-196],[229,-162],[15,115],[130,15],[201,-131],[-33,-157],[135,-53],[71,163],[149,-300],[3,136],[795,977]],[[37726,65053],[-587,-4044],[-148,108],[-31,-573],[39,-36],[-111,-1294],[-60,-565],[-72,-1010],[48,-611]],[[38002,64928],[-276,125]],[[34913,86569],[188,540],[43,307],[129,301],[-73,738],[122,391],[15,239],[103,324],[146,680],[69,208],[94,91],[94,233],[255,452],[93,66]],[[32287,83386],[591,800],[206,352],[205,-318],[313,-369],[354,667],[-47,147],[365,192],[164,131],[186,361],[165,108],[58,248],[-51,286],[85,268],[32,310]],[[29909,86079],[305,495],[255,296],[280,-377],[511,-886],[192,153],[181,298],[188,-490],[279,-482],[189,-722],[42,-392],[-44,-586]],[[28085,90593],[132,-259],[552,114],[45,-92],[223,-731],[-100,-138],[-78,-1069],[297,-347],[190,-411],[-167,-265],[388,-771],[342,-545]],[[36191,91139],[447,3549],[391,-278],[282,1420],[238,932],[-2,81],[-468,867],[-269,597],[-180,631],[-125,292],[-513,769],[-777,-862],[-444,-410],[-478,-847],[-538,-1024],[-138,321],[-463,-1127],[-912,-557],[13,-64],[-183,-160],[-360,-405],[-395,-579],[99,-249],[-552,-881],[57,-97],[-533,-1048],[-329,-411],[-431,-160],[-475,-240],[-256,587],[-20,-167],[-206,-254],[-63,72],[-230,-183],[-102,-138],[-197,-434],[6,-89]],[[44320,73395],[-76,-312],[-37,-1884],[-30,-1002],[22,-781],[-64,-276],[39,-1039],[227,-138],[-108,-732],[2,-375]],[[50536,71263],[-291,435],[-452,489],[-409,688],[-189,289],[-188,-117],[-416,103],[-240,14],[-289,147],[-57,130],[-95,505],[-117,198],[-281,119],[-178,174],[-270,77],[-112,121],[-535,384],[-592,207],[-831,580],[-674,-2411]],[[51079,69182],[-271,1009],[-132,871],[-140,201]],[[44295,66856],[362,-125],[52,-154],[89,288],[24,-245],[234,42],[97,-146],[176,251],[146,29],[279,-165],[602,-619],[565,-349],[178,-259],[127,-286],[175,-236],[383,-254],[81,58],[383,-3],[562,-178],[752,-570],[184,242],[149,389],[207,657],[449,-365],[378,179],[203,227],[420,290],[354,455],[-425,255],[-425,124],[10,46],[292,166],[198,239],[264,414],[-282,338],[-142,-214],[-159,158],[-234,70],[-48,362],[-194,-1],[318,1216]],[[32428,70363],[138,37],[-43,972],[17,1075],[80,-18],[27,609],[348,24],[38,632],[131,59]],[[31159,78295],[-138,-396],[-103,-108],[-149,245],[-79,429],[-260,-402],[-116,344],[-103,465],[-35,283],[-405,37],[-193,-17],[-369,-136],[-385,-374],[-392,-417],[-137,-258],[-162,112],[-337,-2],[-38,234],[77,122],[-131,531],[-142,809],[-163,810],[-189,244],[-106,55],[53,-767],[137,-1432],[285,-650],[343,-362],[132,-571],[309,-599],[317,-234],[60,-332],[166,-520],[69,-724],[81,-558],[-57,-478],[80,-1009],[191,31],[89,-1672],[294,38],[103,-545],[76,-14],[710,-409],[245,-18],[382,48],[605,160],[279,12],[375,63]],[[33164,73753],[-14,602],[-45,814],[86,425],[-66,538],[-8,284],[-79,1290],[-630,155],[-165,235],[-352,380],[-467,91],[-265,-272]],[[40580,85215],[-168,470],[-15,217],[121,439],[383,1746],[3,177],[-64,178],[30,409],[240,1227],[-908,847],[-80,-60],[-140,64],[-310,-20],[-376,70],[-718,345],[-1009,418],[-260,-170],[-858,-404],[-260,-29]],[[36697,83787],[71,250],[163,393],[417,-190],[20,266],[385,-64],[-4,-63],[605,-153],[796,-58],[259,-35],[231,247],[122,69],[259,-14],[8,-204],[-56,-200],[30,-263],[110,-117],[360,65],[25,246],[79,7],[59,580],[-4,365],[-52,301]],[[34913,86569],[689,-1108],[405,-777],[-70,-270],[760,-627]],[[50296,94442],[-191,687],[-479,1518],[-202,490],[-290,614],[-284,480],[-234,261],[-395,292],[-186,60],[-430,12],[-221,-74],[-467,-339],[-800,-730],[-258,-206],[32,-562],[-8,-606],[-28,-456],[18,-236],[147,-422],[336,-482],[196,-418],[119,-520],[30,-435],[-70,-3038]],[[46631,90332],[773,-755],[172,586],[-88,497],[164,332],[66,219],[137,746],[34,578],[177,1027],[29,424],[558,-142],[168,11],[396,127],[349,181],[464,283],[266,-4]],[[36697,83787],[-86,-393],[345,-357],[253,-124],[4,-49],[-187,-832],[122,-96],[250,57],[-39,-182],[227,-222],[-148,-421],[171,-234],[218,-439],[96,-136],[-121,-167],[158,-362],[301,-570],[6,-176],[225,-397],[73,123],[240,-132],[268,-323],[-85,-64],[-13,-310],[198,-601],[180,-305],[278,-332],[247,-244],[35,122],[295,-301]],[[41554,80571],[-113,1125],[45,652],[4,323],[51,257],[-7,414],[-70,553],[-170,219],[10,281],[-407,96],[5,302],[-35,604],[-164,-47],[-123,-135]],[[40208,76320],[189,645],[304,-234],[47,520],[138,2029],[123,1178],[545,113]],[[37726,65053],[-397,159],[-454,-106],[-455,139],[-303,193],[-729,770],[34,241],[-651,420],[-97,-442],[-198,-65],[-177,-327],[-24,-114],[-245,-29],[-214,-205],[-200,-66],[-53,-334],[-155,26],[-46,-291],[-89,50],[-76,-213]],[[36028,54078],[290,383],[172,315],[465,1163],[-23,476],[-115,249],[-13,364]],[[32264,54341],[598,75],[254,62],[222,-5],[118,147],[126,44],[130,-58],[383,108],[189,126],[214,231],[520,317],[200,66],[369,-47],[136,-148],[134,-25],[143,-131],[30,-386],[-2,-639]],[[33197,64859],[-64,-493],[-313,-1393],[-178,-1064],[-440,13],[-87,-144],[-102,-20],[-260,-1791],[74,-1021],[247,-2755],[123,-1258],[67,-592]],[[46603,89158],[-482,280],[-174,168],[-147,-266],[-513,-392],[-94,-181],[-49,-237],[-24,-498],[-76,-226],[-206,-343],[55,-227],[-140,-103],[-42,184],[-162,-273],[-496,-1791],[-57,-102],[-15,-425],[-145,6],[14,-224],[-459,-1746],[-1092,-2683]],[[50536,71263],[-96,755],[-99,446],[22,986],[-26,517],[-372,648],[-185,451],[-273,389],[-324,1025],[-212,478],[-166,447],[-364,558],[-227,247],[-206,-42],[-131,332],[40,845],[-29,266],[-89,390],[-103,150],[-359,283],[-254,97],[-202,266],[-323,897],[-8,466],[58,1245],[-89,680],[-24,421],[108,4652]],[[42299,80079],[-51,-392],[-360,-136],[57,-397],[-21,-393],[-104,-590],[275,35],[304,208],[275,-91],[19,-251],[438,-162],[-2,-195],[389,-127],[-14,-232],[363,-78],[-5,-915],[-22,-408],[359,-60],[-6,-270],[-203,-379],[-112,-560],[-136,-379],[-15,-230],[593,-682]],[[51079,69182],[233,550],[187,115],[755,-337],[196,37],[178,323],[170,76],[194,-92],[507,355]],[[46631,90332],[-28,-1174]],[[54886,86511],[-774,583],[-289,315],[-146,259],[-327,711],[-123,378],[-91,410],[-346,1978],[-165,479],[-196,220],[-960,391],[-322,226],[-218,294],[-163,293],[-193,441],[-158,491],[-119,462]],[[53499,70209],[172,660],[22,555],[54,445],[89,508],[106,343],[121,229],[112,842],[93,586],[188,208],[281,135],[-67,864],[-163,386],[-112,406],[-31,352],[-119,606],[-16,525],[22,622],[-33,1281],[-6,1723],[62,563],[74,1380],[83,731],[176,779],[279,1573]],[[32287,83386],[-341,-1348],[-184,-902],[-462,-851],[-184,-513],[37,-482],[6,-995]],[[40455,74979],[49,734],[57,250],[-362,327],[9,30]],[[33164,73753],[261,-17],[46,136],[39,-132],[396,-176],[134,-189],[86,132],[270,-38],[-2,139],[133,-102],[-8,303],[226,-82],[80,57],[48,187],[197,49],[303,148],[584,15],[480,-74],[699,-142],[323,4],[266,71],[524,342],[1311,256],[235,12],[55,159],[263,189],[342,-21]],[[42896,47248],[-23,452],[-132,637],[53,-5],[-117,930],[468,2982],[113,188],[226,557],[152,171],[69,255],[121,152],[59,185],[-128,486],[-139,306],[-88,107],[141,444],[-82,172]],[[39658,47103],[375,637],[175,161],[204,543],[63,458],[142,430],[244,-445],[356,-547],[513,75],[257,126],[-10,53],[229,167],[197,-653],[229,-904],[264,44]],[[36028,54078],[434,-1498],[228,-208],[135,-190],[424,-131],[186,-86],[549,-349],[144,-233],[135,-334],[210,-675],[379,231],[350,-419],[135,-517],[357,-115],[-22,-130],[7,-761],[85,-174],[22,-370],[-121,-401],[-67,-510],[60,-105]],[[40455,74979],[672,77],[260,-81],[156,-161],[236,-10],[133,-66],[99,-607],[-138,-364],[-124,-152],[-98,-295],[66,-433],[-85,-468],[30,-219],[-104,-48],[-152,-245],[-185,-134],[-89,27],[131,-292],[-379,-280],[-94,-125],[28,-91],[-267,-419],[28,-206],[-405,-98],[-67,-459],[-488,26],[-39,-322],[-308,21],[-200,-449],[-165,-296],[37,-472],[36,-97],[10,-373],[-77,-32],[-9,-162],[-902,-2746]],[[42299,80079],[-634,156],[-77,61],[-34,275]],[[44292,66386],[3,470]],[[28085,90593],[16,-51],[-208,-288],[-47,-226],[-239,-336],[-123,-373],[-179,-67],[51,-374],[-229,-1379],[254,-495],[280,-1265],[-144,-903],[77,-476],[202,-288],[439,274],[404,-399],[84,19],[399,367],[300,658],[9,141],[245,254],[233,693]],[[32428,70363],[116,-869],[25,-1008],[-11,-968],[569,38],[14,-1065],[-17,-226],[-37,-1280],[110,-126]],[[32264,54341],[-446,-71],[-715,-18],[-915,11],[-371,-207],[-107,-96],[-338,-419],[-278,-275],[-190,-59],[-450,2],[-184,31],[-345,182],[-758,246],[-196,-15],[-96,-112],[-378,-137],[-248,-54],[-883,-477],[-315,-223],[-31,-80]],[[34761,48491],[-58,241],[-21,651],[-65,586],[64,474],[66,296],[144,358],[1,609],[-58,239],[-80,119],[-216,667],[59,213],[34,333],[165,213],[-32,121],[165,141],[334,105],[551,103],[214,118]],[[28320,47202],[338,-522],[850,-953],[497,-310],[529,260],[357,115],[1180,430],[1123,543],[636,399],[452,873],[479,454]],[[25020,52570],[1084,122],[227,-39],[282,-520],[353,-1265],[240,-560],[273,-557],[355,-1128],[195,-684],[291,-737]],[[31083,37747],[-864,-858],[-613,-673],[-103,-217],[288,-536],[31,-7],[468,-784],[184,-195],[235,-560],[222,-334],[35,-123]],[[35133,46671],[5,-59],[-228,-32],[-52,-204],[-57,-451],[-228,-769],[161,-333],[-12,-171],[442,-576],[33,-142],[-325,-721],[-758,-1313],[-790,-513],[-573,-639],[-821,-1488],[-499,-862],[-348,-651]],[[38239,43891],[-126,188],[-110,302],[-97,153],[-249,147],[-175,557],[-272,295],[-248,10],[-195,171],[-154,475],[-120,186],[-467,432],[-309,34],[-378,-191],[-206,21]],[[38269,43612],[-30,279]],[[31529,32512],[34,0],[791,390],[561,256],[1309,325],[1268,143],[811,-40],[462,-165],[1072,-204],[1685,331],[606,240],[-48,227],[-135,335],[-75,507],[-96,212],[-200,190],[-195,364],[-242,281],[-152,2],[-88,-126],[-183,57],[-131,223],[-79,241],[-137,163],[-45,493],[-142,192],[-13,217],[44,273],[-51,437],[-63,189],[6,215],[-52,243],[114,505],[22,536],[94,551],[37,500],[-7,404],[-61,309],[27,760],[43,255],[-6,304],[-99,614],[54,151]],[[30966,33460],[144,-380],[199,135],[42,-208],[178,-495]],[[17691,47750],[278,284],[867,788],[403,291],[818,-27],[299,-51]],[[20356,49035],[-211,932],[-989,2487],[-167,892],[-54,1327],[-431,-267],[-990,-443],[-301,-309],[-340,-188],[-408,109],[-127,-491],[-230,-480],[76,-497],[87,-1015],[-141,-313],[-697,-925],[-163,-161],[319,-355],[-216,-673],[-237,-652],[-104,-432],[399,-1035],[310,-143],[608,340],[1102,760],[240,247]],[[29199,38750],[91,587],[60,180],[-94,163],[81,171],[-78,193],[69,82],[-16,268],[48,265],[79,185],[-57,104],[55,556],[123,161],[-137,556],[126,163],[77,626],[-777,1613],[-436,1227],[-93,1352]],[[25078,40219],[15,-86],[359,-312],[748,-355],[146,-24],[542,44],[706,-25],[306,-64],[267,-2],[179,-267],[209,-478],[564,170],[80,-70]],[[21553,50014],[255,-86],[399,-439],[341,144],[226,-85],[370,56],[234,-12],[472,-149],[41,-164],[155,-155],[40,-134],[19,-519],[48,-465],[89,-369],[438,-1058],[54,-198],[32,-380],[-135,-1575],[42,-1066],[-86,-217],[-243,-420],[-118,-614],[3,-479],[44,-337],[93,-346],[679,-603],[33,-125]],[[25020,52570],[-631,-763],[-572,-30],[-935,-419],[-434,-252],[-250,-489],[-645,-603]],[[42896,47248],[20,-478],[136,28],[23,452],[193,-87],[-287,-909],[-186,-427],[107,-245],[116,20],[-74,-644],[-181,-1302],[-139,-50],[-164,-153],[-256,-679],[187,-267],[245,34],[99,156],[137,-76],[182,-253],[185,-66],[171,-217],[286,-30],[198,-108],[287,53],[146,73],[233,-88],[-13,-208]],[[44547,41777],[400,40],[412,252],[280,-267],[50,2153],[-138,866],[189,998],[-3,1508],[126,692],[193,378],[55,601],[91,257],[84,464],[-13,261],[57,454],[143,917],[132,596],[89,653],[-87,921],[17,1206],[323,-179],[289,607],[-196,122],[-366,894],[-263,378],[-129,364],[-179,246],[-318,53],[-698,732],[-161,306],[-131,41],[-324,-30],[-413,69],[-212,143]],[[38269,43612],[426,-191],[140,58],[114,-82],[378,150],[13,-127],[130,-168],[126,-296],[173,-222],[-18,-496],[-103,-596],[385,-172],[-19,-267],[-90,-344],[-16,-213],[300,-621],[581,-67],[738,1203],[385,610],[304,-151],[717,-104],[564,-388],[827,631],[223,18]],[[39658,47103],[-96,-244],[-150,-207],[-277,-570],[-135,-228],[-124,-423],[-147,-223],[-479,-1182],[-11,-135]],[[31083,37747],[-1222,602],[-643,335],[-19,66]],[[26256,20725],[-114,722],[-176,765],[-145,834],[354,840],[327,464],[424,903],[-32,1020],[164,788],[245,822],[373,739],[645,644],[380,457],[154,107],[495,905],[553,1043],[606,1037],[457,645]],[[21155,27732],[306,-133],[134,35],[69,139],[57,413],[181,197],[302,-277],[411,-432],[257,-217],[174,-59],[244,3],[511,263],[102,124],[1,-965],[14,-304],[-69,-223],[29,-252],[-69,-504],[108,-486],[-28,-490],[69,-477],[-38,-220],[42,-274],[61,-96],[39,-432],[48,-39],[66,-309],[153,-51],[47,-272],[125,-98],[358,180],[203,-133],[26,-646],[539,-530],[245,-153],[384,-289]],[[20571,33249],[100,-52],[89,-239],[154,-590],[-66,-639],[10,-923],[-41,-500],[122,-736],[97,-421],[128,-428],[32,-458],[-41,-531]],[[25078,40219],[-71,-173],[103,-307],[-41,-473],[12,-1875],[-288,-17],[-30,-228],[-29,-926],[56,-534],[154,-1033],[35,-73],[101,-536],[-53,-93],[52,-848],[-204,42],[-100,176],[-180,91],[-49,220],[-241,156],[-263,450],[-182,465],[-28,275],[-116,331],[-687,-816],[-309,-314],[-187,-237],[-498,-794],[-135,-169],[-258,-121],[-413,198],[-264,167],[-394,26]],[[19207,33662],[-367,-257],[-239,-210],[-392,-22],[-476,-283],[-223,31],[-322,184],[-324,300],[-201,103],[-599,153],[-93,-264],[-254,-269],[-111,14],[-198,-109],[-403,-868],[-586,6],[-519,-81],[-181,33],[-148,99],[-197,55],[-90,-50],[-241,18],[-95,-41],[-386,140],[-95,93],[-491,80],[-306,157],[-403,277],[-153,-6],[-282,154],[-56,-74],[-354,202],[-327,67],[-297,179],[-110,-111],[-193,31],[-10,-110],[-526,-138],[-115,4],[-204,177],[-457,162],[-216,12]],[[20571,33249],[-253,-189],[-239,79],[-589,337],[-283,186]],[[7967,33500],[326,-425],[228,-162],[720,-185],[81,-895],[96,-594],[158,-728],[238,-1401],[154,-516],[487,2],[312,140],[337,18],[11,-148],[223,-1292],[54,-432],[178,-911],[7,-113],[306,3],[404,-321],[269,-354],[116,-79],[489,-47],[216,-129],[330,30],[248,-144],[116,-234],[-145,-264],[-37,-1740],[27,-343],[156,-720],[229,-983],[-725,-1867],[459,-100],[852,-221],[777,-140],[392,-30],[981,-24],[573,647],[98,385],[-16,659],[192,797],[-5,426],[476,1081],[243,227],[-59,127],[-4,351],[-39,146],[52,276],[-34,227],[-25,793],[-80,673],[57,339],[68,177],[-31,229],[-156,262],[-104,345],[101,763],[-107,252],[145,355],[112,451],[79,141],[83,-52],[137,-449],[30,-264],[166,-257],[167,-160],[206,-50],[214,146],[103,218],[58,448],[-28,186],[-149,325],[-18,439],[100,130],[221,-13],[212,48],[191,129],[105,-15],[168,-227],[61,-195],[37,-444],[83,-346],[81,-87],[207,1],[147,-59]],[[34761,48491],[202,-457],[61,-383],[78,-155],[122,187],[56,-271],[-167,-510],[20,-231]],[[7967,33500],[12,442],[173,1303],[299,1418],[33,835],[40,380],[12,1169],[29,486],[245,212],[144,264],[-10,109],[136,403],[-33,527],[-58,107],[-380,424],[-310,127],[-98,123],[-195,69],[-95,162],[-223,-75],[-37,243],[-75,-63],[-142,55],[-68,-114],[-176,-22],[-103,226],[-154,112],[-171,42],[-141,-133],[-344,-167],[-95,22],[-159,173],[-237,-116],[-167,132],[-407,148],[-77,-97],[-175,80],[-180,-242],[-160,33],[-138,212],[-76,-107],[-79,41],[-169,246],[-421,266],[-128,-53],[-173,73],[-168,293],[-155,-27],[-84,341],[55,243],[-130,79],[-155,238],[-295,317],[-21,148],[-137,415],[-25,176],[-151,267],[-153,49],[-448,-138],[-400,68],[-108,130],[-113,-1],[-142,189],[-238,-368],[-61,20],[-182,-419],[83,-445],[-6,-206],[64,-253],[-159,-647],[-85,-136],[-109,-340],[-100,-185],[18,-417],[57,-76],[-19,-259],[86,-322],[4,-250],[455,-279],[235,-224],[245,-321],[896,-46],[43,-211],[292,70],[182,-299],[-74,-292],[64,-225],[3,-469],[30,-147],[358,-289],[14,-330],[77,-322],[161,-221],[137,-103],[-23,-115],[113,-63],[277,-257],[163,-625],[129,-37],[293,-227],[211,-452],[299,-415],[272,-141],[138,-119],[-16,-698],[-95,-696],[128,-35],[92,107],[688,-214],[798,-306],[552,-73],[352,117],[319,-2]],[[21553,50014],[-930,-967],[-267,-12]],[[17691,47750],[193,-526],[-36,-56],[83,-239],[-107,-122],[128,-374],[63,59],[355,-511],[159,-519],[400,-877],[422,-638],[348,-1052],[85,-320],[-2,-400],[139,-547],[-5,-259],[59,-389],[75,-106],[111,-380],[223,-366],[16,-224],[78,-297],[-146,-1090],[-450,-1197],[-228,-1430],[22,-226],[-17,-540],[-225,-691],[-83,-514],[-144,-257]],[[26256,20725],[171,-26],[680,-283],[482,28],[352,189],[102,222],[196,272],[794,1270],[111,247],[92,82],[60,-121],[287,-44],[380,-245],[57,-71],[367,-190],[279,901],[153,418],[773,3185],[426,1212],[223,425],[78,612],[38,21],[3,614],[-112,409],[-273,778],[-113,136],[-113,268],[16,322],[-55,345],[-288,713],[107,98]],[[66026,79859],[-12,-162],[45,-713],[-547,-955],[-282,-224],[508,-1457],[-61,-718],[-107,-1030],[73,-486],[136,-396],[631,-134],[317,-387]],[[66477,82734],[-90,-360],[28,-366],[-213,-241],[-30,-458],[-175,-40],[37,-246],[16,-436],[41,-327],[-8,-218],[61,-33],[-118,-150]],[[72885,73848],[-43,126],[-99,778],[44,1609],[-51,529],[-165,711],[-21,240],[175,517],[213,455],[10,185],[-70,565],[49,318],[-42,268],[-171,132],[-178,348],[-239,208],[-208,-47],[-132,-132],[-161,-10],[-154,185],[-98,205],[-224,99],[-265,262],[-350,221],[-289,147],[-301,242],[-211,86],[-65,-38],[-457,277],[-77,151],[-173,128],[-219,94],[-148,-82],[-117,70],[-57,196],[-129,-34],[-241,29],[-258,84],[-101,247],[-437,-330],[-135,18],[-250,168],[-306,-108],[-118,-166],[-31,112],[-108,-177]],[[73179,73134],[-55,78],[-239,636]],[[73195,72591],[48,369],[-64,174]],[[70047,67511],[99,26],[164,504],[395,543],[367,949],[680,1637],[1014,1476],[429,-55]],[[66727,73197],[195,-162],[244,-108],[237,-620],[134,-704],[40,-404],[-15,-960],[70,-663],[355,77],[91,-130],[85,-475],[165,-619],[185,-500],[328,-324],[189,-30],[359,169],[289,-68],[107,-243],[262,78]],[[63174,84140],[157,213],[118,84],[206,36],[207,-131],[28,431],[48,65],[20,458],[163,202]],[[61995,81679],[41,304],[63,17],[75,494],[110,352],[261,501],[611,842],[18,-49]],[[56721,86001],[0,-498],[858,-45],[651,190],[1135,736],[944,595],[184,43],[490,185],[19,-210],[-53,-208],[93,-87],[296,-1001],[-143,-433],[-11,-240],[82,-325],[313,-592],[54,-175],[-35,-652],[23,-334],[146,-560],[71,-438],[157,-273]],[[64121,85498],[40,177],[-140,220],[-27,259],[-87,-66],[-152,78],[-132,-143],[-144,-32],[-170,254],[-43,137],[-223,-157],[-95,237],[-101,-4],[-53,243],[39,152],[-12,277],[-152,175],[-66,428],[-117,180],[-90,1],[-121,-407],[-148,100],[-79,-367],[-86,60],[-13,245],[-157,143],[-76,-122],[-65,55],[-253,-160],[-113,31],[-171,320],[-53,429],[-161,938],[-1213,-1314],[-402,-476],[-691,-924],[-402,-354],[-435,-153],[-1036,43]],[[68226,52139],[-582,657],[-161,221],[-151,1746],[-290,456],[-220,75]],[[67900,45733],[326,659],[-12,769],[-28,409],[-63,90],[-339,275],[-150,249],[-91,822],[30,215],[142,259],[176,213],[103,347],[165,772],[-97,620],[16,233],[93,201],[55,273]],[[65068,37536],[20,274],[100,437],[541,1143],[219,300],[195,515],[94,410],[117,634],[34,378],[75,349],[184,483],[129,566],[-343,296],[-96,140],[201,285],[366,435],[630,980],[213,243],[1,146],[152,183]],[[63416,36607],[-73,437],[15,137],[236,743],[183,173],[17,220],[134,788],[106,203],[268,328],[66,262],[76,-34],[278,77],[181,-49],[158,-242],[-37,-514],[-91,-339],[-44,-547],[68,-123],[38,-448],[73,-143]],[[62442,39103],[72,-188],[7,-361],[43,-456],[-7,-196],[535,-608],[209,-587],[115,-100]],[[60389,48326],[76,-442],[136,-62],[-33,-91],[330,-269],[-14,-147],[751,-1011],[209,-211],[-90,-339],[407,-916],[122,-340],[150,-583],[73,-510],[-34,-32],[116,-464],[-79,-313],[47,-511],[-82,-1238],[20,-360],[-45,-421],[-7,-963]],[[61339,50014],[-950,-1688]],[[64558,56917],[-566,-226],[-186,-827],[-342,-565],[-357,-839],[6,-712],[-259,-642],[-864,-1754],[-651,-1338]],[[66822,55294],[-240,22],[-441,362],[-389,131],[-432,482],[-762,626]],[[54097,65173],[315,451],[19,395],[285,119],[70,129],[91,386],[93,217],[170,198],[58,164],[249,308],[-129,711],[-159,-84],[-63,-118],[-338,237],[161,251],[-53,483],[175,52],[366,510],[183,47],[70,419],[111,167],[-2,-283],[184,36],[591,-80],[628,696],[347,1056],[283,-269],[85,-139],[269,-270],[233,74],[199,-67],[744,-332],[229,-307],[394,-226],[599,-131],[43,217],[155,190],[792,391],[22,-97],[788,415],[10,-16]],[[53499,70209],[39,-927],[-145,-1452],[205,-1282],[254,-992],[245,-383]],[[61662,80065],[-162,-775],[-118,-139],[-31,-151],[68,-486],[-9,-208],[-153,-402],[-175,-109],[55,-290],[-24,-440],[-428,-471],[-435,-364],[-327,-502],[-298,-393],[-428,-270],[-276,-304],[-240,-377],[-97,-344],[-147,-334],[-129,113],[-72,-459],[-165,76],[-660,-759],[-247,-304],[-104,18],[-237,-248],[-196,-71],[-721,146],[-577,477],[-229,-85],[-457,51],[-57,-316],[-19,-371],[-130,-140],[-273,-746],[-255,-481],[-208,-249],[-202,-149]],[[62364,71073],[-77,526],[-18,643],[-93,936],[-37,1135],[-155,2445],[-52,1373],[-17,787],[-262,-14],[39,846],[-30,315]],[[61995,81679],[36,-179],[-94,-526],[-13,-233],[-219,-349],[-43,-327]],[[66026,79859],[-197,-6],[-302,-326],[-141,-329],[-379,534],[-220,-591],[-394,157],[163,202],[-178,353],[-93,414],[-503,472],[-138,470],[-117,1140],[28,380],[161,229],[-171,61],[-217,591],[-154,530]],[[62364,71073],[297,429],[-18,259],[426,1],[-20,299],[242,2],[690,84],[44,-415],[104,-388],[174,-178],[246,-56],[109,-242],[108,38],[284,335],[116,61],[140,-133],[358,-486],[242,34],[104,245],[347,1119],[296,778],[74,338]],[[66477,82734],[-271,456],[-229,57],[-3,-190],[-391,189],[-348,263],[-368,168],[-231,242],[-95,293],[-169,286],[-87,248],[10,295],[-174,457]],[[71709,64445],[322,-184],[203,-263]],[[70047,67511],[54,-371],[-110,-263],[-62,-257],[355,-383],[187,-326],[134,-149],[278,259],[396,591],[128,-13],[54,110],[91,-28],[-144,-349],[36,-138],[96,40],[93,-99],[-23,-269],[-106,-285],[39,-175],[142,-47],[30,-275],[96,-183],[248,-85],[-350,-371]],[[72601,68729],[-196,-45],[142,556],[199,283],[52,578],[289,260],[17,601],[132,114],[-33,136],[73,495],[90,331],[-63,256],[-141,137],[33,160]],[[73234,64700],[-195,25],[-263,242],[-265,150],[-163,221],[70,221],[-69,271],[-88,12],[-19,180],[-129,-6],[120,447],[-41,524],[127,191],[90,-177],[-7,-248],[235,15],[39,-141],[77,128],[-17,423],[237,88],[-65,356],[179,-19],[-33,427],[-133,444],[-82,126],[-118,-99],[-92,-181],[-108,50],[80,359]],[[72234,63998],[40,-53],[212,5],[33,148],[183,-197],[108,360],[297,-100],[199,8],[-72,531]],[[73179,73134],[111,243],[-390,604],[-15,-133]],[[71178,52588],[-329,524],[-102,1058],[-53,949],[-63,652],[-20,818],[212,1341],[135,1201],[-141,53],[12,274],[-54,290],[-14,303],[115,918]],[[68226,52139],[14,217],[343,-29],[314,370],[192,95],[178,165],[275,-94],[119,-165],[53,-195],[72,-529],[888,370],[504,244]],[[71709,64445],[-285,107],[-459,251],[-61,300],[-128,425],[-152,60],[-154,245],[-466,-61],[-211,-621],[-196,-662],[-221,-396],[-104,-725],[-114,-208],[-295,-23],[-254,-185],[-44,267],[-101,284],[-199,77],[-84,-245],[-226,-470],[-38,-201],[-126,-249],[-152,-171],[-386,-246],[-109,-27],[113,796],[87,245],[-62,63],[-134,-419],[-60,-608],[94,-208],[-74,-228],[50,-63],[-229,-681],[-90,176],[-307,-721],[23,-240],[-161,-403],[-133,-529],[-26,-244],[99,-736],[54,-174],[232,-339],[196,-443],[324,-173],[164,-190],[49,-151],[36,-355],[-13,-285],[-145,-238],[-190,-155],[-219,-374]],[[70876,60969],[95,486],[161,467],[606,1164],[291,339],[205,573]],[[60376,58130],[723,89],[1132,247],[640,118],[1560,-1343],[127,-324]],[[54097,65173],[290,-420],[824,234],[1104,-937],[1101,-573],[814,86],[558,-505],[78,-307],[78,-143],[262,-760],[425,-775],[176,-576],[267,-983],[302,-1384]],[[61339,50014],[-411,539],[-680,615],[-593,780],[-347,155],[-645,-176],[-34,93]],[[56461,40051],[576,2027],[548,1403],[408,830],[660,1379],[302,596],[154,578],[767,1026],[513,436]],[[58629,52020],[-59,-152],[-137,-60],[-112,42],[-153,-212],[-229,-14],[-248,-178],[-106,-186],[-80,-381],[-113,-392],[-553,-943],[-84,-165],[-143,-522],[-139,-321],[24,-119],[-234,-2360],[29,-657],[-49,-119],[-48,-352],[-11,-430],[415,-1028],[155,-1207],[-85,-451],[-226,-962],[18,-800]],[[56721,86001],[-623,32],[-409,67],[-501,210],[-302,201]],[[71460,49670],[-66,766],[47,849],[9,844],[-272,459]],[[70924,47063],[56,607],[85,446],[-42,446],[-137,353],[241,241],[333,514]],[[67900,45733],[760,495],[-29,281],[65,315],[118,375],[90,138],[218,12],[134,-173],[-126,-389],[282,-139],[285,-67],[215,200],[159,42],[93,-236],[181,96],[109,401],[470,-21]],[[60376,58130],[-204,15],[-99,-257],[-182,-137],[-73,-156],[-28,-260],[-427,-1270],[-54,-356],[-207,-437],[-245,-422],[-45,-181],[26,-209],[-112,-261],[13,-225],[-111,-301],[4,-307],[90,-596],[-3,-291],[-90,-459]],[[58510,32941],[400,355],[62,580],[171,738],[278,-15],[574,1084],[200,554],[114,237],[179,86],[667,56],[215,55],[189,249],[228,160],[238,590],[161,853],[244,490],[12,90]],[[54768,34020],[533,-527],[321,753],[498,-90],[731,98],[229,0],[304,-123],[844,-992],[282,-198]],[[56461,40051],[-261,-1553],[-147,-1022],[-352,-2363],[-933,-1093]],[[93795,50104],[74,-55],[114,135],[72,-74],[203,207],[223,-360],[163,-129],[59,-440],[104,-362],[70,-353],[-39,-147],[70,-377],[-97,-163],[158,-123],[43,-333],[120,-432],[14,-272],[164,6],[180,-300],[137,-547],[84,-3],[-1,235],[-58,460],[63,55],[560,298],[1328,-175]],[[96515,55172],[-61,5],[-113,-275],[-52,-433],[-49,-25],[-144,272],[-517,-582],[-81,118],[-487,-506],[-170,-583],[-58,-404],[23,-659],[-41,-556],[-64,98],[-312,-181],[-148,-403],[-291,-642],[-79,-251],[-76,-61]],[[97603,46855],[113,1047],[143,101],[258,-13],[66,513],[258,438],[110,393],[112,167],[107,-35],[181,504],[36,228],[202,280],[139,-24],[-2,146],[-142,189],[66,185],[122,63],[58,124],[-25,356],[-70,327],[-106,143],[-160,78],[94,127],[-107,227],[68,243],[46,491],[109,490],[-12,180],[-195,149],[-1003,1594],[-106,48],[-65,353],[-237,-243],[-21,83],[-230,-230],[-45,189],[-401,-324],[-449,-270]],[[80316,61638],[-220,243],[-146,300]],[[81081,52665],[374,834],[18,469],[-250,2051],[-405,2729],[24,234],[126,661],[-215,407],[-91,610],[-224,536],[-122,442]],[[78388,54962],[959,-737],[1734,-1560]],[[79950,62181],[-238,-213],[-469,-66],[-165,-337],[-165,-523],[-55,-304],[-184,-364],[-72,-221],[155,-814],[58,-1080],[-98,-836],[-134,-599],[-195,-1862]],[[80796,35497],[-102,-475],[-49,-509],[25,-525],[33,-213],[158,-484],[81,-452],[50,-62],[-134,-142],[-26,-629],[-122,-162],[49,-146],[-105,-85],[-42,136],[-122,-204],[-24,88],[-294,-403],[-179,47],[205,-443],[-190,-379],[-114,-656],[275,-612]],[[81573,36732],[-46,-633],[-140,219],[-84,-321],[-87,83],[-56,-283],[-364,-300]],[[82397,36419],[-127,19],[-407,188],[-290,106]],[[83820,31366],[28,163],[-74,272],[-132,760],[-302,1179],[-445,1642],[-498,1037]],[[80169,29187],[145,556],[2303,712],[1123,586],[80,325]],[[84405,82290],[-164,-47],[-199,103],[25,-612],[-100,-1085],[113,-283],[34,-222],[-17,-621],[-248,-491],[-336,-218],[-637,-88],[-454,-374],[-326,-377],[-219,-302],[46,-190],[-151,-78],[-193,145],[-34,-1689],[-508,133],[-12,29],[-102,-1390]],[[89446,72890],[-37,269],[-91,-112],[4,708],[-92,816],[-72,165],[-267,269],[-833,357],[-386,269],[-398,779],[-297,802],[-261,795],[-368,-310],[-38,274],[6,1037],[-57,645],[29,880],[104,286],[26,646],[72,436],[-203,180],[-216,-75],[-270,-285],[-116,-175],[-100,-293],[-221,-853],[-517,16],[-344,-32],[64,1246],[-63,469],[-99,191]],[[85567,68839],[880,265],[434,599],[562,694],[167,346],[287,265],[793,192],[248,316],[626,539],[-118,835]],[[84810,66804],[120,536],[496,1291],[141,208]],[[81719,69918],[185,-319],[128,-311],[211,-74],[-47,-275],[99,-249],[131,-161],[98,-31],[-6,-227],[247,-19],[92,-177],[112,-87],[-109,-386],[263,-195],[176,48],[299,-97],[66,131],[411,-390],[378,-179],[357,-116]],[[80923,74633],[357,-109],[16,-49],[24,-1318],[17,-245],[128,-630],[-7,-499],[104,-9],[66,-286],[-40,-504],[56,-453],[137,-6],[-62,-607]],[[79484,45158],[485,361],[238,-57],[156,41],[145,-37],[182,-177],[189,-28],[42,-145],[-27,-419],[128,-108],[168,-47],[221,413],[108,379],[462,684]],[[81065,50381],[-952,-649],[-623,-1014],[52,-1885],[-58,-1675]],[[81981,46018],[280,164],[468,620],[107,110],[70,448],[-93,151],[-270,82],[-275,-30],[-178,327],[-31,214],[49,251],[-443,686],[-199,827],[-401,513]],[[87596,53627],[-218,533],[-118,387],[-85,410],[-77,527],[-652,123],[-233,102],[-158,200],[-254,244],[-363,261],[-277,351],[-662,1399],[-239,693],[-242,770],[101,1113],[-355,897],[219,856]],[[86842,48615],[-235,564],[-226,670],[51,455],[172,950],[-36,984],[777,1134],[251,255]],[[83859,42808],[804,-142],[166,24],[267,737],[150,881],[231,629],[301,1122],[181,535],[200,676],[119,633],[246,-335],[257,406],[61,641]],[[82618,44705],[284,-683],[388,-377],[110,-367],[192,-259],[267,-211]],[[81981,46018],[322,-630],[315,-683]],[[81081,52665],[-91,-526],[-37,-691],[112,-1067]],[[83983,62493],[-2907,-654],[-448,-95],[-312,-106]],[[85434,39597],[-94,-66],[40,-298],[194,-396],[42,-252],[100,-213],[-12,-260],[-912,-1117],[-228,-690],[-217,246],[-631,153],[-232,141],[-170,208],[-336,-104],[-426,254],[-155,-784]],[[87487,33690],[-330,1307],[-203,871],[-179,1081],[-169,345],[-221,550],[-311,593],[-224,358],[-416,802]],[[88510,30854],[32,239],[-189,378],[-301,750],[-565,1469]],[[87140,28385],[317,-438],[256,216],[-34,453],[163,426],[-131,281],[101,464],[-127,310],[4,231],[295,99],[364,346],[162,81]],[[83820,31366],[654,-653],[748,-547],[1054,-936],[388,-511],[238,-225],[238,-109]],[[90958,65234],[-19,3214],[-820,1760],[-110,1021],[-108,581],[13,623],[-468,457]],[[89468,62513],[256,1078],[-22,15],[190,661],[258,507],[153,562],[655,-102]],[[85567,68839],[793,-902],[471,-355],[277,-628],[329,-1017],[330,-2523],[422,-363],[333,-73],[391,5],[243,-155],[312,-315]],[[72265,49962],[132,853],[152,1126],[70,661],[97,641],[132,411],[321,-522],[64,70],[67,575],[42,802],[235,672],[652,1033],[46,445],[-313,131],[-25,324],[81,305],[-312,609],[116,-24],[-414,663],[56,0],[1,238],[200,-60],[-3,704],[184,-7],[-124,293],[-227,278],[-142,38],[-190,210],[-114,-97],[11,-199],[-512,113],[-63,-146],[-140,220],[-130,288],[-120,-125],[-218,180],[-103,232],[41,817],[-10,361],[-85,90],[-237,-490],[-206,-592],[-34,-345],[-367,231]],[[71460,49670],[634,-317],[171,609]],[[78728,28784],[320,69],[300,102],[609,-222],[190,-38],[164,-243],[-3,289],[-139,446]],[[78908,36711],[2,-718],[-32,-993],[-12,-2608],[-115,-1999],[-110,-983],[30,-629],[57,3]],[[80796,35497],[-1026,539],[-862,675]],[[91139,39800],[-190,45],[-123,923],[-27,431],[-86,145],[-112,941],[-114,457],[-119,105],[-183,363],[-243,586]],[[91939,38658],[-121,71],[-487,499],[-192,572]],[[88381,36342],[104,-68],[230,-378],[238,-205],[149,27],[233,-138],[264,-64],[7,269],[-59,232],[-51,433],[119,551],[164,-136],[-37,218],[273,32],[-64,356],[172,-32],[280,-311],[97,-54],[64,219],[75,65],[56,471],[238,78],[147,-247],[105,-34],[12,335],[123,260],[198,-291],[137,168],[68,210],[216,350]],[[89942,43796],[209,-629],[270,-480],[86,-224],[-62,-67],[-1042,-855],[-248,-187],[-172,180],[-54,-93],[-258,-1721],[-334,-1283],[50,-1160],[176,-626],[-182,-309]],[[80836,16122],[100,273],[462,490],[283,131],[390,258],[253,273],[157,451],[1374,632],[198,214],[-24,401],[346,315],[159,66],[186,-79],[523,-111],[157,-115],[95,102],[191,327],[185,197],[381,480],[329,322],[427,-422],[127,433],[-76,208],[2,262],[-49,197],[70,149],[67,453],[-49,283],[-183,227],[-8,159],[-139,77],[-44,432],[-121,156],[-378,-160],[-55,31],[-212,482],[-41,22],[-447,1884],[449,572],[513,358],[377,1625],[329,208]],[[80738,24389],[145,-89],[14,-330],[-48,-219],[190,-820],[236,-1145],[123,-980],[-26,-469],[74,-610],[98,-370],[-42,-374],[-142,-484],[-19,-264],[-186,-710],[-118,-591],[-201,-812]],[[78728,28784],[930,-1215],[229,-582],[451,-1268],[400,-1330]],[[79494,78311],[15,-390],[-43,-508],[279,-150],[-64,-319],[171,-279],[-117,-492],[-3,-217],[-111,-322],[166,-161],[90,-306],[241,-244],[159,-75],[646,-215]],[[84405,82290],[-120,958],[-9,501],[-295,671],[-168,765],[-369,1339],[-223,23],[-96,138],[-70,235],[-394,492],[-241,-279],[-262,-371],[-404,-498],[-257,-23],[-535,510],[-381,172],[-360,38],[-556,-203],[130,-515],[103,-285],[97,-110],[-184,-708],[-140,69],[62,-1860],[12,-80],[-82,-504],[32,-66],[16,-979],[-9,-574],[-40,-703],[10,-337],[-40,-212],[-131,-404],[-7,-1179]],[[75454,66633],[199,232],[571,1129],[-66,1650],[-280,684],[-216,161]],[[73234,64700],[441,909],[465,753],[802,-53],[452,365],[60,-41]],[[75662,70489],[-183,-128],[-119,44],[-82,-86],[-429,93],[-326,521],[-119,-305],[-97,226],[-74,334],[61,49],[-86,240],[-113,-298],[-102,-622],[158,-40],[175,-697],[-317,-269],[14,361],[-197,-3],[-67,132],[-85,-85],[-48,127],[-216,-190],[-201,-463],[-220,-325],[-81,-313],[-307,-63]],[[96679,33971],[368,171],[321,27],[94,474],[125,-26],[309,328],[408,74],[226,-135],[259,-60],[152,-158],[150,473],[-140,64],[-135,208],[387,687],[-68,252],[78,195],[252,314],[328,294],[206,282],[-183,556],[-787,1527],[-898,2266],[169,372],[129,104],[-620,3192],[-206,1403]],[[92613,38056],[66,-553],[142,-921],[442,99],[306,-5],[233,-70],[142,122],[480,330],[346,152],[492,59],[224,-152],[139,-230],[581,-633],[190,-292],[347,-729],[161,-590],[-225,-672]],[[93795,50104],[-101,-127],[30,-703],[33,-1404],[-32,-431],[326,-66],[-342,-1305],[415,-675],[96,-351],[20,-331],[-359,-264],[251,-1014],[-77,-111],[58,-528],[-262,-86],[243,-585],[-342,-248],[293,-264],[-213,-62],[-260,-169],[95,-309],[-301,-331],[-111,-207],[136,-594],[-147,-137],[-313,-189],[78,-358],[66,-132],[-268,-299],[-72,-204],[-122,-564]],[[84810,66804],[-191,-929],[-168,-578],[-81,-1093],[-180,-568],[-207,-1143]],[[89288,55074],[-315,750],[-183,1011],[-167,1645],[-50,897],[103,1238],[544,358],[78,323],[170,1217]],[[88760,49736],[265,54],[112,108],[282,624],[248,103],[164,-106],[132,2],[-55,543],[220,145],[111,215],[-152,26],[-163,142],[-205,100],[31,183],[104,229],[-223,418],[76,196],[-9,518],[-141,413],[-165,4],[-25,500],[-79,921]],[[87596,53627],[248,-701],[57,-528],[158,-553],[101,-549],[325,-635],[74,-375],[201,-550]],[[79691,63716],[207,-916],[52,-619]],[[81719,69918],[-116,-1018],[-91,-416],[-192,-435],[-145,-828],[-212,43],[-48,-62],[-83,-426],[-77,-32],[-108,-517],[-37,-324],[-93,-444],[60,-24],[-179,-276],[-116,-292],[-348,-562],[-243,-589]],[[96515,55172],[22,345],[104,426],[46,870],[84,687],[111,408],[22,658],[40,488],[20,560],[166,883],[39,902],[71,-15],[23,500],[-42,541],[-25,853],[42,390],[-11,215],[177,595],[173,825],[-165,245],[-113,-28],[-67,-179],[-484,-618],[-722,-494],[-97,-92],[-405,-256],[-95,-145],[-113,5],[-136,288],[-318,83],[-265,-95],[-197,540],[-404,-365],[-964,67],[-274,276],[-110,190],[-262,79],[-176,254],[-174,157],[-1078,19]],[[89288,55074],[161,-27],[409,-346],[169,-779],[129,-388],[102,-208],[120,-79],[240,-338],[49,122],[-153,620],[88,96],[462,-87],[405,38],[234,-53],[57,-66],[76,-370],[134,-387],[322,-468],[213,-365],[233,-236],[249,-171],[404,-484],[127,-458],[61,57],[198,-233],[62,-173],[-44,-187]],[[82618,44705],[-83,-177],[119,-345],[-183,-431],[196,-119],[98,-167],[9,-146],[-93,-68],[-287,-819],[-78,-890],[21,-858],[-290,-135],[-56,588],[-90,13],[-54,-328],[56,-614],[22,-448],[65,-183],[-46,-467],[-168,23],[19,-333],[-26,-319],[41,-172],[-4,-303],[-70,-480],[-163,-795]],[[85434,39597],[-97,226],[-298,133],[-170,267],[-182,425],[117,208],[-637,1282],[-308,670]],[[87487,33690],[423,-148],[367,281],[-254,581],[149,1070],[209,868]],[[89942,43796],[-145,292],[-94,87],[-172,-24],[-226,155],[-297,-60],[-51,404],[-146,185],[-245,416],[-130,310],[-156,262],[-178,462],[-257,975],[-183,316],[-179,165],[-238,296],[-403,578]],[[79691,63716],[-63,314],[-279,-164],[-164,-54],[-439,-49],[-365,-158],[-426,56],[-528,389],[-336,451],[-514,810],[-266,164],[-358,159],[-55,410],[-153,274],[-291,315]],[[76867,51185],[381,954],[432,355],[383,901],[325,1567]],[[72265,49962],[222,325],[134,263],[122,800],[197,611],[116,557],[141,349],[112,101],[271,11],[320,348],[130,-217],[99,154],[118,-148],[349,-1],[8,60],[357,27],[-3,-104],[110,-37],[31,422],[84,-109],[-3,-178],[196,-19],[-3,-243],[123,-7],[485,-150],[-21,-131],[365,-266],[-99,-457],[278,-147],[36,68],[177,-218],[-42,-218],[104,-45],[88,-178]],[[91139,39800],[24,374],[-6,430],[38,469],[-8,261],[242,153],[158,49],[-167,335],[-224,155],[-92,377],[-10,263],[-86,389],[-307,891],[145,117],[3,294],[-364,341],[-97,9],[-307,462],[-592,670],[-167,426],[360,-94],[416,56],[264,87],[285,178],[203,297],[103,54],[12,216],[-242,94],[-215,-123],[-37,168],[-324,36],[-179,142],[-84,205],[-128,-27],[-166,240],[-70,298],[-130,239],[-218,100],[-111,148],[-134,654],[-72,145],[-95,358]],[[79484,45158],[-151,409],[-40,13],[-236,520]],[[79170,37859],[59,97],[-39,304],[11,658],[-44,306],[-213,391],[44,180],[157,-45],[75,187],[20,551],[128,165],[13,521],[64,443],[73,185],[-73,51],[-3,378],[72,714],[32,142],[-57,286],[3,241],[-50,27],[42,1517]],[[72872,38910],[263,40],[207,126],[182,-51],[43,273],[447,-238],[-26,-335],[564,-214],[195,109],[492,608],[36,164],[136,-61],[99,146],[369,260],[66,-74],[38,-280],[140,78],[-22,148],[129,94],[313,-737],[311,-653],[339,-591],[178,-119],[445,-106],[38,-306],[165,82],[12,124],[813,356],[100,84],[56,207],[170,-185]],[[72581,40015],[264,-309],[-38,-96],[86,-145],[27,-384],[-48,-171]],[[79057,46100],[-145,-266],[-124,401],[-25,327],[-479,-115],[-342,-218],[-194,301],[-239,-12],[-17,-170],[-449,-89],[-297,93],[-85,181],[-65,-64],[-144,-345],[-69,397],[43,278],[-97,107],[-144,-823],[-17,-340],[-214,-258],[-12,-366],[-118,-146],[-117,37],[-106,-90],[-252,-625],[-304,-416],[-313,-223],[-76,-389],[-124,-159],[-249,-755],[199,-308],[-301,-705],[-184,-249],[-159,-23],[-55,-524],[-123,-43],[-235,189],[-23,-99],[-243,277],[-219,-418],[-275,-297],[-84,-138]],[[76867,51185],[654,-993],[155,-393],[177,-536],[185,-316],[352,-763],[263,-483],[256,-246],[-34,-280],[57,-310],[-4,-400],[129,-365]],[[91939,38658],[329,-28],[77,-257],[268,-317]],[[79494,78311],[-145,-65],[-369,-249],[-846,-2000],[53,-301],[-193,-130],[-82,57],[-67,-99],[-446,-844],[-466,-742],[-135,-48],[-280,-1079],[-81,-362],[-375,-961],[-248,-535],[-152,-464]],[[79170,37859],[-84,-233],[-71,-514],[-99,-5],[-8,-396]],[[88510,30854],[260,-53],[646,-1182],[499,-819],[224,-402],[253,-282],[54,-126],[167,574],[303,192],[235,-720],[200,-434],[321,-440],[176,-140],[193,391],[333,377],[386,241],[180,158],[500,361],[182,194],[496,-142],[190,421],[130,140],[238,143],[331,427],[434,319],[160,260],[474,979],[-151,1130],[-136,508],[151,168],[166,341],[199,154],[101,174],[92,11],[182,194]],[[70924,47063],[-58,-167],[-35,-606],[83,-415],[349,-342],[133,-345],[87,-125],[352,-648],[-70,-484],[89,-199],[-101,-161],[77,-694],[119,-664],[-108,-137],[92,-324],[83,-159],[294,-203],[142,-279],[40,-240],[-22,-243],[61,-8],[-38,-495],[88,-110]],[[58238,31289],[88,159],[226,207],[289,165],[375,165],[335,101],[396,-229],[418,-106],[198,-1025],[380,30],[627,-192],[203,597],[213,250],[382,-302],[236,-132],[253,-389],[471,-24],[249,-155],[207,-78],[92,-101]],[[58510,32941],[18,-609],[-261,-834],[-29,-209]],[[63876,30230],[-149,1108],[-72,145],[34,159],[261,237],[118,229],[-121,571],[61,433],[84,932],[214,574],[36,362],[-18,587],[-293,980],[-305,56],[-310,4]],[[73081,17384],[55,608],[58,343],[-25,953],[95,-1],[98,151],[-103,379],[-117,1087],[-169,625],[-58,308],[84,401],[-40,502],[51,342]],[[71320,17214],[372,15],[180,45],[51,-75],[446,9],[97,102],[540,184],[75,-110]],[[69453,26167],[6,-281],[-45,-116],[-44,-670],[37,-193],[159,-422],[143,-465],[23,-416],[86,-796],[5,-373],[79,-144],[55,-360],[257,-531],[213,-134],[25,-139],[179,-362],[40,-791],[353,-1095],[322,-612],[-26,-1053]],[[69818,32817],[-5,-1872],[-38,-1117],[-135,-2111],[1,-243],[-127,-592],[59,-58],[-88,-250],[-32,-407]],[[73173,33377],[-68,-157],[62,-469],[-7,-299],[-78,-199],[-17,-215],[-199,-4],[-278,376],[-368,121],[-444,268],[-339,-492],[-71,-306],[-307,-557],[-463,563],[-152,283],[-191,707],[-435,-180]],[[73010,23082],[172,948],[169,86],[491,398],[155,321],[72,551],[-30,913],[-32,381],[136,890],[116,335],[-44,980],[64,290],[9,807],[-176,459],[0,429],[-329,151],[-183,200],[21,295],[92,264],[-142,511],[-398,1086]],[[53640,26786],[150,349],[114,132],[197,475],[164,148],[33,182],[-165,225],[-30,469],[0,894],[-44,250],[-270,150],[-37,407],[-211,316],[-66,306],[-403,649]],[[49748,18691],[540,-137],[199,21],[251,105],[327,245],[372,195],[157,42],[574,49],[293,249],[161,178],[416,549],[94,175],[112,672],[-232,435],[-227,64],[-60,69],[171,365],[-6,293],[125,266],[-57,186],[21,346],[-65,119],[51,243],[194,267],[375,743],[177,929],[-107,60],[36,1367]],[[53072,31738],[-240,-66],[-622,-312],[-2806,404],[-1094,-1],[186,-1783],[191,-2514],[67,-2209],[198,-3404],[83,-688],[-156,-130],[-189,-51],[-274,-145],[-63,-308],[66,-765],[357,-1025],[177,48],[566,-47],[229,-51]],[[73010,23082],[370,-13],[205,-168],[340,-70],[473,524],[236,195],[831,185],[157,150],[117,-96],[211,118],[174,-195],[202,140],[142,343],[72,72],[303,617],[86,340],[27,-70],[48,442],[-14,338],[31,78],[166,-180],[137,155],[50,-121],[131,227],[1232,-537],[544,-352],[956,-1184],[242,128],[259,241]],[[72872,38910],[-120,-371],[-56,-288],[-73,-723],[118,-379],[21,-837],[112,-612],[-91,-93],[14,-649],[94,-622],[36,-362],[71,-187],[226,-366],[-51,-44]],[[75625,10841],[470,33],[200,224],[281,-83],[116,48],[302,19],[82,-53],[243,92],[164,-18],[242,51],[155,91],[233,12],[-3,76],[257,260],[296,47],[222,117],[77,102],[481,256],[321,566],[160,483],[202,1074],[245,635],[1,219],[64,391],[243,356],[157,283]],[[73081,17384],[189,23],[28,-283],[72,-201],[-35,-259],[36,-154],[193,-374],[287,-280],[235,-133],[221,-194],[89,-167],[243,-312],[189,-124],[60,54],[-5,-232],[-122,-252],[-175,-174],[-127,-228],[42,-264],[68,-71],[-166,-67],[36,-419],[112,-318],[293,-360],[189,-564],[154,-35],[104,-153],[221,-476],[113,-526]],[[67992,34643],[307,-412],[43,47],[254,-215],[-76,-209],[135,-314],[143,-95],[-15,-120],[153,-234],[141,126],[54,-118],[357,578],[97,-4],[77,-426],[156,-430]],[[67900,45733],[729,-1164],[185,-313],[52,-235],[102,-914],[90,-359],[75,4],[-46,-295],[285,-1429],[119,-112],[-55,-222],[-112,-126],[31,-155],[210,-412],[74,-20],[-9,-203],[-139,-981],[-31,-382],[-110,-435],[-200,-206],[-269,-541],[-254,-696],[-299,-351],[-141,-432],[-165,-684],[37,-193],[-67,-234]],[[65068,37536],[-118,-261],[-119,-1200],[-63,-1120],[89,-446],[214,-286],[440,354],[1383,119],[571,-169],[217,-130],[310,246]],[[63474,12737],[817,-4005],[953,-2499],[418,-1054],[898,-1561],[475,-809],[421,-508],[1550,-225],[374,46],[443,-565],[-39,-1122],[215,-63],[402,280],[172,42],[376,-19],[194,-104],[165,51],[165,-47],[136,95],[285,73],[110,-120],[98,1],[243,-161],[9,-463],[1300,529],[-13,211],[149,1505],[141,1561],[-61,1466],[210,1639],[201,1029],[703,2353],[505,575],[136,-27]],[[70800,17293],[-525,-993],[-1102,-1260],[-815,-1260],[-169,-485],[-1054,112],[-1325,-506],[-828,171],[-431,-311],[-1077,-24]],[[71320,17214],[-276,-7],[-244,86]],[[56952,14620],[20,716],[-32,1042],[-120,2119],[-15,537],[210,1140],[-421,1515],[-27,1906],[-24,708],[-434,397],[-368,266],[-738,412],[-1363,1408]],[[49748,18691],[-18,-489],[-95,-478],[141,-223],[20,-453],[178,-568],[-48,-954],[70,-607],[33,-711],[110,-1382],[484,141],[468,73],[855,179],[1656,434],[1278,375],[719,282],[1353,310]],[[63258,20762],[-16,101],[-132,52],[-364,-47],[-1,452],[-85,509],[715,-50],[103,476],[345,853],[156,693],[-196,704],[-81,424],[-68,684],[-96,234],[-67,298]],[[60829,18033],[264,-15],[433,-346],[253,109],[-33,223],[-159,308],[-23,170],[137,120],[18,346],[397,108],[17,121],[-140,617],[-110,263],[235,83],[192,196],[295,21],[208,173],[188,37],[235,121],[22,74]],[[59974,24244],[209,-544],[275,-500],[190,-442],[130,-1641],[-121,-916],[69,-488],[-44,-569],[18,-475],[129,-636]],[[63471,26145],[-140,-322],[-249,-78],[-194,-119],[-169,-42],[-169,-276],[-151,-63],[-802,-643],[-278,-335],[-216,-187],[-403,-196],[-226,27],[-500,333]],[[64417,27867],[244,-195],[222,-89],[64,-541],[147,12],[43,-219],[245,360],[-149,165],[4,275],[-110,115],[-104,233],[-110,373],[-245,1219],[514,74],[436,178],[918,2],[4,-561],[-101,-206],[91,-495],[148,-1098],[52,110],[-5,256],[213,-31],[37,307],[508,1632],[541,524],[356,377],[409,-474],[707,-239],[-257,-1372],[-137,-654],[-324,-371],[-242,-209],[-254,-467],[168,-257],[225,-112],[107,-377],[83,-177],[415,269],[173,-37]],[[63876,30230],[86,-688],[-19,-789],[189,-570],[285,-316]],[[63258,20762],[174,45],[380,-36],[316,-89],[773,-41],[132,9],[195,821],[-95,117],[41,283],[-127,58],[90,252],[168,-147],[246,-56],[194,21],[268,-187],[181,278],[239,-142],[38,378],[167,-30],[-7,-209],[113,-126],[-15,-403],[50,-178],[193,-128],[155,-11],[362,-174],[140,-18],[248,-150],[352,-270],[298,-288],[113,-32],[424,-282],[216,110],[190,-146],[273,-325],[37,34],[131,-210],[147,-527],[-73,-705],[-98,-329],[913,-636]],[[64417,27867],[-9,-161],[-367,-453],[-309,-568],[-261,-540]],[[54768,34020],[-1069,-1548],[-466,-689],[-161,-45]],[[59974,24244],[-163,752],[-53,1552],[-559,1289],[-500,997],[-130,227],[-177,430],[-102,688],[-52,1110]],[[58966,15130],[-252,525],[-9,170],[104,226],[-25,113],[96,325],[12,194],[464,851],[461,590],[303,5],[133,-123],[224,93],[352,-66]],[[56952,14620],[2014,510]],[[58966,15130],[250,65],[153,-45],[584,-252],[301,-73],[165,-98],[253,-73],[122,-100],[313,-30],[366,-149],[327,-172],[1328,-549],[173,-19],[173,-898]]],"transform":{"scale":[0.009175646763764669,-0.004800048000480004],"translate":[21.222249635148444,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/bs.json b/src/onegov/election_day/static/mapdata/2025/bs.json new file mode 100644 index 0000000000..2cca2cee81 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/bs.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":2701,"properties":{"id":2701,"name":"Basel"},"arcs":[[-1,-2]]},{"type":"Polygon","id":2702,"properties":{"id":2702,"name":"Bettingen"},"arcs":[[-3,-4]]},{"type":"Polygon","id":2703,"properties":{"id":2703,"name":"Riehen"},"arcs":[[3,-5,0,-6]]}]}},"arcs":[[[56094,51679],[1102,4940],[-2021,2931],[-658,-584],[-779,-651],[-787,-627],[-1985,3239],[166,134],[-548,896],[-697,-1147],[-253,-141],[-208,127],[-484,789],[-522,1321],[-847,3301],[1857,2391],[2609,2434],[-1782,2526]],[[50257,73558],[-428,-314],[-1122,-986],[-1288,-977],[-1049,-846],[-1748,985],[-1248,380],[-1273,196],[-1357,23],[-1373,1],[-1121,-106],[-2136,-278],[319,2457],[-411,636],[-51,938],[-167,150],[-294,48],[375,1805],[165,2593],[-4576,3301],[-3813,1624],[-2969,1121],[-566,-1689],[-920,-2410],[-891,-3011],[-702,-3955],[-242,-2782],[195,-3741],[-2804,941],[-1372,453],[-1766,-266],[-826,-385],[-2620,1183],[-1825,366],[-1863,308],[-755,-1773],[-2177,-1648],[-3962,-2953],[-309,-1319],[2069,-2439],[-766,-2621],[-691,-2710],[-1899,-816],[2359,-2124],[572,-808],[829,-1743],[1236,-1651],[2146,-2395],[12,-222],[-1094,-2577],[-1297,-3923],[-1794,768],[-2053,-9806],[473,-4],[719,84],[1351,355],[1033,307],[460,191],[1097,262],[1197,471],[77,-3],[2016,-524],[2542,-629],[3299,-953],[1726,-192],[270,-77],[115,74],[375,54],[661,3],[335,-55],[311,-122],[366,167],[4172,-2342],[-305,-809],[-230,-895],[-570,-1687],[-155,-593],[-11,-422],[68,-203],[258,-402],[-14,-489],[-611,-1726],[-639,-1653],[-509,-1446],[-334,-633],[-223,-581],[67,-598],[284,-607],[489,-694],[331,251],[485,198],[502,54],[103,-846],[60,-821],[-26,-835],[1872,-265],[-54,-603],[62,-337],[184,-222],[202,-132],[340,-89],[254,-1037],[66,-489],[31,-1145],[-231,-710],[-22,-893],[-152,-873],[-54,-927],[86,-809],[168,-570],[168,-1270],[254,-1219],[354,-170],[2912,-431],[2168,3224],[2850,4188],[1749,4039],[356,788],[-64,619],[666,-17],[-43,635],[142,309],[-28,229],[282,45],[-18,238],[2276,4949],[746,754],[191,-509],[643,285],[-254,627],[566,572],[18,184],[278,128],[310,339],[140,476],[75,1075],[55,348],[191,481],[307,394],[255,197],[413,205],[17,-46],[1310,556],[330,172],[304,225],[272,275],[234,317],[106,20],[346,-253],[367,-207],[386,-157],[1829,-617],[320,8107],[131,3531],[-61,807],[-178,772],[-274,721],[-370,662],[-218,303],[-616,649],[-1240,1057],[-328,328],[-267,394],[-251,600],[-84,486],[12,331],[149,1547],[14,909],[-80,1246],[-79,618],[1186,571],[2403,1342],[1275,674],[2142,939],[1017,204],[1029,34],[944,-69],[776,-171]],[[70520,52053],[1361,725],[1166,-105],[430,1042],[815,900],[616,753],[1428,392],[2509,747],[954,-411],[1393,303],[1421,442],[543,210],[346,-20],[1196,-454],[-35,-536],[104,-1561],[1444,-324],[836,33],[1223,327],[-30,1453],[-1538,593],[395,630],[751,1283],[672,1007],[543,1415],[473,660],[1379,1145],[1780,1010],[157,-878],[-97,-1124],[-107,-1461],[239,-84],[1568,-3346],[223,847],[422,1701],[195,846],[1032,1901],[250,430],[545,1360],[-536,1254],[-2455,801],[-865,863],[-457,133],[100,2106],[22,1259],[-940,698],[-468,273],[17,309],[-232,2025],[-187,1991]],[[91121,75616],[-393,160],[-1003,-907],[-535,-302],[6,-461],[-125,-499],[-395,-949],[-159,-564],[-32,-590],[-164,-774],[-68,-626],[-25,-653],[224,-1718],[-200,-258],[-267,28],[-204,-108],[-244,-374],[-411,-219],[-660,226],[-1525,93],[-757,-437],[-1089,-154],[-661,401],[-1764,673],[-19,370],[-279,284],[-266,131],[-193,22],[-377,-74],[-226,606],[-1451,-537],[-379,-503],[-312,-780],[-287,-241],[635,-1326],[-693,-483],[304,-533],[-696,-676],[-197,-296],[-293,258],[-372,-876],[-167,-542],[-590,-1205],[-77,-493],[-815,-1428],[-462,-1567],[-190,-797],[-663,-1162],[-739,-1192],[-592,-1024],[-391,-535],[-565,-545],[202,-407]],[[56094,51679],[79,6],[902,-349],[1549,3298],[1593,-841],[1272,-1496],[841,-896],[2008,30],[1452,-689],[317,-268],[1276,-688],[1489,1186],[1648,1081]],[[91121,75616],[-369,2065],[-1386,704],[-1451,577],[-1424,599],[-2065,1222],[-242,2482],[960,1097],[1045,1313],[2038,2607],[1580,1087],[1718,2469],[1193,2156],[768,754],[3907,1156],[1306,1355],[761,995],[539,1572],[-336,173],[-1210,-1627],[-1668,-915],[-956,-291],[-692,109],[-1584,79],[-1301,-340],[-1045,-1421],[-641,-175],[-674,-1021],[-1186,-1231],[-919,-1278],[-919,-1554],[-232,-1300],[-2143,-109],[-3497,46],[-1951,873],[-2110,1261],[-4770,2054],[-2883,384],[-1470,618],[-2408,885],[-906,-1489],[-976,-853],[-905,-1046],[56,-1570],[999,-1912],[-2594,-1201],[-2291,-2444],[-581,-968],[-546,-997],[-545,-1113],[-1068,-1323],[-1086,-1383],[-1071,-1398],[-1138,-1401],[-1138,-1182],[-1026,-964],[-331,-244]]],"transform":{"scale":[0.005519701186492806,-0.004800048000480005],"translate":[204.01770052595293,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/fr.json b/src/onegov/election_day/static/mapdata/2025/fr.json new file mode 100644 index 0000000000..f798fbcff9 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/fr.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":2008,"properties":{"id":2008,"name":"Châtillon (FR)"},"arcs":[[-1,-2,-3,-4]]},{"type":"Polygon","id":2011,"properties":{"id":2011,"name":"Cugy (FR)"},"arcs":[[-5,-6,-7,-8,-9]]},{"type":"Polygon","id":2016,"properties":{"id":2016,"name":"Fétigny"},"arcs":[[-10,6,-11]]},{"type":"Polygon","id":2022,"properties":{"id":2022,"name":"Gletterens"},"arcs":[[-12,-13,-14]]},{"type":"Polygon","id":2025,"properties":{"id":2025,"name":"Lully (FR)"},"arcs":[[3,-15,-16,-17,-18,-19]]},{"type":"Polygon","id":2027,"properties":{"id":2027,"name":"Ménières"},"arcs":[[7,9,-20,-21]]},{"type":"MultiPolygon","id":2029,"properties":{"id":2029,"name":"Montagny (FR)"},"arcs":[[[-22,-23,-24,-25,-26]]]},{"type":"Polygon","id":2035,"properties":{"id":2035,"name":"Nuvilly"},"arcs":[[-27,-28,-29]]},{"type":"Polygon","id":2038,"properties":{"id":2038,"name":"Prévondavaux"},"arcs":[[-30,-31]]},{"type":"Polygon","id":2041,"properties":{"id":2041,"name":"Saint-Aubin (FR)"},"arcs":[[-32,-33,-34,-35,-36]]},{"type":"Polygon","id":2043,"properties":{"id":2043,"name":"Sévaz"},"arcs":[[-37,-38]]},{"type":"Polygon","id":2044,"properties":{"id":2044,"name":"Surpierre"},"arcs":[[30,-39]]},{"type":"Polygon","id":2045,"properties":{"id":2045,"name":"Vallon"},"arcs":[[-40,12,-41,33]]},{"type":"Polygon","id":2050,"properties":{"id":2050,"name":"Les Montets"},"arcs":[[20,-42,26,-43,15,-44,37,-45,8]]},{"type":"Polygon","id":2051,"properties":{"id":2051,"name":"Delley-Portalban"},"arcs":[[40,11,-46,34]]},{"type":"Polygon","id":2053,"properties":{"id":2053,"name":"Belmont-Broye"},"arcs":[[-47,23,-48,31,-49,-50]]},{"type":"MultiPolygon","id":2054,"properties":{"id":2054,"name":"Estavayer"},"arcs":[[[4,44,36,43,14,2,-51,-52]],[[28,-53,-54,16,42]],[[-55]],[[-56,0,18]]]},{"type":"Polygon","id":2055,"properties":{"id":2055,"name":"Cheyres-Châbles"},"arcs":[[50,1,55,17,53,-57]]},{"type":"Polygon","id":2063,"properties":{"id":2063,"name":"Billens-Hennens"},"arcs":[[-58,-59,-60]]},{"type":"Polygon","id":2067,"properties":{"id":2067,"name":"Le Châtelard"},"arcs":[[-61,-62,-63,-64,-65]]},{"type":"Polygon","id":2068,"properties":{"id":2068,"name":"Châtonnaye"},"arcs":[[-66,-67,-68]]},{"type":"Polygon","id":2079,"properties":{"id":2079,"name":"Grangettes"},"arcs":[[-69,-70,-71,62,-72]]},{"type":"Polygon","id":2086,"properties":{"id":2086,"name":"Massonnens"},"arcs":[[-73,-74,-75,63,70,-76]]},{"type":"Polygon","id":2087,"properties":{"id":2087,"name":"Mézières (FR)"},"arcs":[[-77,-78,-79,-80,72]]},{"type":"Polygon","id":2096,"properties":{"id":2096,"name":"Romont (FR)"},"arcs":[[-81,78,-82,57,-83]]},{"type":"Polygon","id":2097,"properties":{"id":2097,"name":"Rue"},"arcs":[[-84,-85,-86]]},{"type":"Polygon","id":2099,"properties":{"id":2099,"name":"Siviriez"},"arcs":[[-87,-88,-89,58,81,77,-90]]},{"type":"Polygon","id":2102,"properties":{"id":2102,"name":"Ursy"},"arcs":[[-91,83,-92,87]]},{"type":"Polygon","id":2113,"properties":{"id":2113,"name":"Vuisternens-devant-Romont"},"arcs":[[-93,-94,-95,89,76,75,69]]},{"type":"Polygon","id":2114,"properties":{"id":2114,"name":"Villorsonnens"},"arcs":[[-96,-97,-98,64,74,-99,-100]]},{"type":"Polygon","id":2115,"properties":{"id":2115,"name":"Torny"},"arcs":[[-101,21,-102,-103,-104,65]]},{"type":"Polygon","id":2117,"properties":{"id":2117,"name":"Villaz"},"arcs":[[103,-105,-106,98,73,79,80,-107,66]]},{"type":"Polygon","id":2121,"properties":{"id":2121,"name":"Haut-Intyamon"},"arcs":[[-108,-109,-110,-111,-112,-113]]},{"type":"Polygon","id":2122,"properties":{"id":2122,"name":"Pont-en-Ogoz"},"arcs":[[-114,-115,-116,-117,-118]]},{"type":"Polygon","id":2123,"properties":{"id":2123,"name":"Botterens"},"arcs":[[-119,-120,-121,-122,-123]]},{"type":"Polygon","id":2124,"properties":{"id":2124,"name":"Broc"},"arcs":[[-124,-125,-126,-127,-128,-129,122]]},{"type":"Polygon","id":2125,"properties":{"id":2125,"name":"Bulle"},"arcs":[[-130,-131,-132,127,-133,-134,-135,-136,-137]]},{"type":"Polygon","id":2128,"properties":{"id":2128,"name":"Châtel-sur-Montsalvens"},"arcs":[[123,121,-138,-139]]},{"type":"Polygon","id":2129,"properties":{"id":2129,"name":"Corbières"},"arcs":[[-140,-141,-142,-143,119]]},{"type":"Polygon","id":2130,"properties":{"id":2130,"name":"Crésuz"},"arcs":[[138,-144,124]]},{"type":"MultiPolygon","id":2131,"properties":{"id":2131,"name":"Echarlens"},"arcs":[[[-145,130,-146,-147,139]],[[136,-148,-149]]]},{"type":"Polygon","id":2134,"properties":{"id":2134,"name":"Grandvillard"},"arcs":[[-150,111,-151,-152]]},{"type":"Polygon","id":2135,"properties":{"id":2135,"name":"Gruyères"},"arcs":[[-153,109,-154,-155,-156,134,-157,132,126,-158]]},{"type":"Polygon","id":2137,"properties":{"id":2137,"name":"Hauteville"},"arcs":[[-159,141,-160,116,-161,-162]]},{"type":"Polygon","id":2138,"properties":{"id":2138,"name":"Jaun"},"arcs":[[-163,-164,-165]]},{"type":"Polygon","id":2140,"properties":{"id":2140,"name":"Marsens"},"arcs":[[71,61,-166,117,159,140,146,-167,-168]]},{"type":"Polygon","id":2143,"properties":{"id":2143,"name":"Morlon"},"arcs":[[118,128,131,144]]},{"type":"Polygon","id":2145,"properties":{"id":2145,"name":"Le Pâquier (FR)"},"arcs":[[133,156]]},{"type":"Polygon","id":2147,"properties":{"id":2147,"name":"Pont-la-Ville"},"arcs":[[-169,160,115,-170,-171]]},{"type":"Polygon","id":2148,"properties":{"id":2148,"name":"Riaz"},"arcs":[[148,-172,-173,-174,166,145,129]]},{"type":"Polygon","id":2149,"properties":{"id":2149,"name":"La Roche"},"arcs":[[-175,-176,-177,-178,161,168]]},{"type":"Polygon","id":2152,"properties":{"id":2152,"name":"Sâles"},"arcs":[[167,173,-179,-180,-181,92,68]]},{"type":"Polygon","id":2153,"properties":{"id":2153,"name":"Sorens"},"arcs":[[-182,113,165,60,97]]},{"type":"Polygon","id":2155,"properties":{"id":2155,"name":"Vaulruz"},"arcs":[[178,172,-183,154,-184]]},{"type":"Polygon","id":2160,"properties":{"id":2160,"name":"Vuadens"},"arcs":[[135,155,182,171,147]]},{"type":"Polygon","id":2162,"properties":{"id":2162,"name":"Bas-Intyamon"},"arcs":[[-185,150,110,152]]},{"type":"Polygon","id":2163,"properties":{"id":2163,"name":"Val-de-Charmey"},"arcs":[[137,120,142,158,177,-186,-187,163,-188,151,184,157,125,143]]},{"type":"Polygon","id":2173,"properties":{"id":2173,"name":"Autigny"},"arcs":[[-189,-190,-191,-192,95]]},{"type":"Polygon","id":2174,"properties":{"id":2174,"name":"Avry"},"arcs":[[-193,-194,-195,-196,-197]]},{"type":"Polygon","id":2175,"properties":{"id":2175,"name":"Belfaux"},"arcs":[[-198,-199,-200,-201,-202]]},{"type":"Polygon","id":2177,"properties":{"id":2177,"name":"Chénens"},"arcs":[[99,105,-203,188]]},{"type":"Polygon","id":2183,"properties":{"id":2183,"name":"Corminboeuf"},"arcs":[[-204,-205,-206,195,-207,-208,197]]},{"type":"Polygon","id":2186,"properties":{"id":2186,"name":"Cottens (FR)"},"arcs":[[-209,-210,-211,190,-212]]},{"type":"Polygon","id":2194,"properties":{"id":2194,"name":"Ferpicloz"},"arcs":[[-213,-214]]},{"type":"Polygon","id":2196,"properties":{"id":2196,"name":"Fribourg"},"arcs":[[-215,-216,-217,-218,-219,-220,-221,-222]]},{"type":"Polygon","id":2197,"properties":{"id":2197,"name":"Givisiez"},"arcs":[[201,-223,-224,217,-225,203]]},{"type":"Polygon","id":2198,"properties":{"id":2198,"name":"Granges-Paccot"},"arcs":[[223,-226,-227,218]]},{"type":"Polygon","id":2206,"properties":{"id":2206,"name":"Marly"},"arcs":[[-228,-229,-230,215,-231,-232]]},{"type":"Polygon","id":2208,"properties":{"id":2208,"name":"Matran"},"arcs":[[196,205,-233,-234,-235]]},{"type":"Polygon","id":2211,"properties":{"id":2211,"name":"Neyruz (FR)"},"arcs":[[234,-236,208,-237,192]]},{"type":"Polygon","id":2216,"properties":{"id":2216,"name":"Pierrafortscha"},"arcs":[[-238,-239,-240,230,214]]},{"type":"Polygon","id":2220,"properties":{"id":2220,"name":"Le Mouret"},"arcs":[[175,-241,-242,213,-243,-244,-245,-246,-247]]},{"type":"Polygon","id":2226,"properties":{"id":2226,"name":"Treyvaux"},"arcs":[[170,-248,-249,240,174]]},{"type":"Polygon","id":2228,"properties":{"id":2228,"name":"Villars-sur-Glâne"},"arcs":[[229,-250,232,204,224,216]]},{"type":"Polygon","id":2230,"properties":{"id":2230,"name":"Villarsel-sur-Marly"},"arcs":[[231,239,-251,243,-252]]},{"type":"Polygon","id":2233,"properties":{"id":2233,"name":"Hauterive (FR)"},"arcs":[[-253,209,235,233,249,228,-254]]},{"type":"Polygon","id":2234,"properties":{"id":2234,"name":"La Brillaz"},"arcs":[[-255,193,236,211,189,202,104,102]]},{"type":"Polygon","id":2235,"properties":{"id":2235,"name":"La Sonnaz"},"arcs":[[-256,-257,225,222,200,-258]]},{"type":"Polygon","id":2236,"properties":{"id":2236,"name":"Gibloux"},"arcs":[[247,169,114,181,96,191,210,252,-259]]},{"type":"Polygon","id":2237,"properties":{"id":2237,"name":"Prez"},"arcs":[[101,25,-260,206,194,254]]},{"type":"Polygon","id":2238,"properties":{"id":2238,"name":"Bois-d'Amont"},"arcs":[[251,242,212,241,248,258,253,227]]},{"type":"Polygon","id":2239,"properties":{"id":2239,"name":"Grolley-Ponthaux"},"arcs":[[-261,198,207,259,24,46]]},{"type":"Polygon","id":2250,"properties":{"id":2250,"name":"Courgevaux"},"arcs":[[-262,-263,-264,-265,-266,-267,-268]]},{"type":"Polygon","id":2254,"properties":{"id":2254,"name":"Courtepin"},"arcs":[[267,-269,-270,-271,-272,255,-273,-274,-275]]},{"type":"Polygon","id":2257,"properties":{"id":2257,"name":"Cressier (FR)"},"arcs":[[-276,-277,-278,269,-279]]},{"type":"Polygon","id":2258,"properties":{"id":2258,"name":"Fräschels"},"arcs":[[-280,-281]]},{"type":"Polygon","id":2261,"properties":{"id":2261,"name":"Greng"},"arcs":[[263,-282,-283,-284]]},{"type":"MultiPolygon","id":2262,"properties":{"id":2262,"name":"Gurmels"},"arcs":[[[-285,-286,-287,-288,-289,270,277,-290]],[[-291]]]},{"type":"Polygon","id":2265,"properties":{"id":2265,"name":"Kerzers"},"arcs":[[-292,-293,279,-294]]},{"type":"Polygon","id":2266,"properties":{"id":2266,"name":"Kleinbösingen"},"arcs":[[-295,-296,287,-297]]},{"type":"Polygon","id":2271,"properties":{"id":2271,"name":"Meyriez"},"arcs":[[-298,-299]]},{"type":"Polygon","id":2272,"properties":{"id":2272,"name":"Misery-Courtion"},"arcs":[[49,-300,272,257,199,260]]},{"type":"Polygon","id":2274,"properties":{"id":2274,"name":"Muntelier"},"arcs":[[-301,-302]]},{"type":"MultiPolygon","id":2275,"properties":{"id":2275,"name":"Murten"},"arcs":[[[289,276,-303,264,283,-304,298,-305,301,-306,-307,-308,-309,-310,-311]],[[-312,278,268,266]],[[274,-313,261]]]},{"type":"Polygon","id":2276,"properties":{"id":2276,"name":"Ried bei Kerzers"},"arcs":[[-314,291,-315,307]]},{"type":"Polygon","id":2278,"properties":{"id":2278,"name":"Ulmiz"},"arcs":[[285,-316,309,-317]]},{"type":"Polygon","id":2284,"properties":{"id":2284,"name":"Mont-Vully"},"arcs":[[305,300,304,297,303,282,-318]]},{"type":"Polygon","id":2292,"properties":{"id":2292,"name":"Brünisried"},"arcs":[[-319,-320,-321,-322]]},{"type":"Polygon","id":2293,"properties":{"id":2293,"name":"Düdingen"},"arcs":[[-323,-324,219,226,256,271,288,295,-325]]},{"type":"Polygon","id":2294,"properties":{"id":2294,"name":"Giffers"},"arcs":[[-326,-327,-328,-329]]},{"type":"Polygon","id":2295,"properties":{"id":2295,"name":"Bösingen"},"arcs":[[324,294,-330,-331,-332]]},{"type":"Polygon","id":2296,"properties":{"id":2296,"name":"Heitenried"},"arcs":[[-333,-334,-335]]},{"type":"Polygon","id":2299,"properties":{"id":2299,"name":"Plaffeien"},"arcs":[[320,-336,-337,164,186,-338,-339]]},{"type":"Polygon","id":2300,"properties":{"id":2300,"name":"Plasselb"},"arcs":[[325,-340,337,185,176,246,-341]]},{"type":"Polygon","id":2301,"properties":{"id":2301,"name":"Rechthalten"},"arcs":[[328,-342,-343,321,338,339]]},{"type":"Polygon","id":2303,"properties":{"id":2303,"name":"St. Silvester"},"arcs":[[340,245,-344,326]]},{"type":"Polygon","id":2304,"properties":{"id":2304,"name":"St. Ursen"},"arcs":[[342,-345,237,221,-346,318]]},{"type":"Polygon","id":2305,"properties":{"id":2305,"name":"Schmitten (FR)"},"arcs":[[331,-347,-348,322]]},{"type":"Polygon","id":2306,"properties":{"id":2306,"name":"Tafers"},"arcs":[[-349,334,-350,335,319,345,220,323,347,-351]]},{"type":"Polygon","id":2307,"properties":{"id":2307,"name":"Tentlingen"},"arcs":[[327,343,244,250,238,344,341]]},{"type":"Polygon","id":2308,"properties":{"id":2308,"name":"Ueberstorf"},"arcs":[[-352,-353,332,348]]},{"type":"Polygon","id":2309,"properties":{"id":2309,"name":"Wünnewil-Flamatt"},"arcs":[[350,346,330,-354,351]]},{"type":"Polygon","id":2321,"properties":{"id":2321,"name":"Attalens"},"arcs":[[-355,-356,-357,-358,-359]]},{"type":"Polygon","id":2323,"properties":{"id":2323,"name":"Bossonnens"},"arcs":[[358,-360,-361]]},{"type":"Polygon","id":2325,"properties":{"id":2325,"name":"Châtel-Saint-Denis"},"arcs":[[-362,-363,-364,-365,107]]},{"type":"Polygon","id":2328,"properties":{"id":2328,"name":"Granges (Veveyse)"},"arcs":[[-366,359,357]]},{"type":"Polygon","id":2333,"properties":{"id":2333,"name":"Remaufens"},"arcs":[[-367,355,-368,362]]},{"type":"Polygon","id":2335,"properties":{"id":2335,"name":"Saint-Martin (FR)"},"arcs":[[-369,-370,-371,-372]]},{"type":"Polygon","id":2336,"properties":{"id":2336,"name":"Semsales"},"arcs":[[108,364,-373,370,-374,179,183,153]]},{"type":"Polygon","id":2337,"properties":{"id":2337,"name":"Le Flon"},"arcs":[[-375,84,90,86,94,-376,368]]},{"type":"Polygon","id":2338,"properties":{"id":2338,"name":"La Verrerie"},"arcs":[[93,180,373,369,375]]},{"type":"Polygon","id":2391,"properties":{"id":2391,"name":"Staatswald Galm"},"arcs":[[310,315,284]]}]}},"arcs":[[[12926,68179],[171,105],[340,-125],[263,156],[204,-184],[647,309],[298,314],[918,286]],[[12492,69448],[57,-184],[-256,-173],[474,-428],[-208,-128],[367,-356]],[[15500,69412],[-529,-20],[-280,379],[-154,59],[-300,333],[-380,-129],[-172,142],[-710,-335],[-244,-43],[178,-242],[-162,-131],[-255,23]],[[15767,69040],[-180,120],[-87,252]],[[25714,68655],[-303,35],[-174,-271],[-687,-123],[-804,-33],[-475,32],[-62,-63],[-734,137],[-538,153],[-151,-90]],[[25869,64664],[-361,107],[10,153],[310,295],[626,765],[-208,282],[-155,394],[177,188],[-320,38],[276,226],[-256,171],[-431,921],[177,451]],[[24330,62800],[253,97],[51,146],[-584,134],[580,252],[271,55],[212,306],[-217,45],[750,489],[223,340]],[[20759,62843],[238,112],[151,-174],[509,88],[612,28],[362,138],[-43,-343],[323,-138],[591,-22],[652,118],[176,150]],[[21786,68432],[209,-409],[-192,-43],[140,-457],[-84,-155],[-326,-46],[271,-509],[-345,-70],[95,-89],[-426,-61],[-263,-111],[-15,-197],[-318,247],[-628,-234],[-17,-133],[-301,45],[-286,-77],[-95,-335],[-211,-72],[-424,-434],[-559,-379],[-65,-214],[156,-53],[388,-624],[174,118],[258,-78],[113,-246],[581,-429],[80,-194],[-168,-409],[44,-127],[520,180],[667,6]],[[24330,62800],[134,-213],[467,107],[334,-205],[58,-155],[-236,-694],[497,-152],[-309,-506],[477,-143]],[[25752,60839],[107,95],[413,-115],[-275,-203],[429,-408],[191,289],[593,378],[194,347],[-101,339],[57,325],[289,321],[363,706],[4,234],[130,129],[574,182],[158,120],[54,262],[168,236],[316,142],[277,404],[-76,226],[-384,190],[-187,321],[-776,-60],[-385,332],[-190,-75],[-630,-476],[156,-134],[-704,-616],[-648,334]],[[32670,81563],[-420,396],[139,211],[-248,252],[-238,22],[-364,163],[-206,-5],[-922,952],[-4401,3938]],[[30923,79515],[380,103],[202,-170],[509,366],[-562,576],[521,246],[-317,308],[1014,619]],[[26010,87492],[-1669,-1617],[3909,-3527],[831,-797],[275,-68],[277,-213],[-220,-273],[-783,-424],[-55,-85],[294,-401],[442,12],[151,91],[335,-170],[267,27],[445,-663],[371,206],[43,-75]],[[18723,69844],[-209,354],[-396,-97],[-27,161],[334,114],[-385,627],[-239,-135],[-84,120],[-574,-170],[24,-212],[-266,48],[-286,-56],[39,-225],[-251,76],[169,205],[0,212],[-571,-91],[-429,69],[-338,-244],[-44,60],[-460,-258],[397,-440],[80,36],[317,-430],[-24,-156]],[[14439,65294],[430,208],[48,280],[838,825],[630,519],[263,82],[406,-144],[104,197],[334,-142],[223,265],[339,41],[-208,251],[63,309],[418,123],[20,176],[-302,295],[156,371],[248,179],[429,192],[-155,523]],[[11472,65750],[256,-13],[157,-139],[-102,-120],[229,-148],[251,222],[170,-202],[119,32],[237,-301],[212,-137],[-14,-267],[818,398],[634,219]],[[13539,67513],[-376,-88],[-586,-244],[-412,-279],[225,-408],[-351,-550],[-180,-112],[-387,-82]],[[15767,69040],[174,-24],[119,-238],[-261,-117],[147,-252],[-141,-195],[182,-274],[-102,-114],[-408,-68],[-392,221],[-53,126],[-525,-302],[-209,30],[-222,-172],[246,-92],[-429,-115],[-138,190],[-216,-131]],[[19046,61074],[-316,-216],[84,-169],[378,-291],[474,-172],[226,2],[385,-263],[131,104],[277,-253],[441,-247],[364,72],[-3,-183],[1351,516],[334,-28],[617,-149],[130,317],[439,44],[317,120],[-108,271],[685,53],[245,-67],[255,304]],[[20759,62843],[237,-158],[133,-317],[-84,-265],[173,-72],[46,-224],[-391,-311],[-251,77],[250,-490],[-347,170],[-404,76],[-661,-90],[-414,-165]],[[33912,62035],[498,-63],[541,-286],[605,-201],[-41,-195],[98,-336],[255,-341],[742,-468],[283,-315],[390,-297]],[[39254,69067],[-424,-392],[0,-309],[-678,-506],[-102,-278],[-1042,206],[-513,-8],[-345,289],[-113,-127],[-322,147],[-278,399],[-406,116],[-46,103],[-688,-824],[-468,-843],[370,-175],[-421,-296],[-164,-198],[143,-285],[288,-194],[-236,-178],[534,-558],[211,-119],[329,-340],[-195,-163],[500,-323],[-183,-165],[69,-117],[-473,-242],[-676,-648],[-100,-204],[-174,-31],[-148,-218],[142,-154],[-76,-357],[343,-40]],[[44198,66852],[-435,-139],[-40,76],[-393,-99],[-366,121],[-312,-179],[-1192,740],[-31,182],[-316,-167],[56,561],[-205,111],[266,170],[-293,328],[-236,-66],[74,201],[-117,140],[-434,-89],[-96,217],[297,-13],[-76,135],[-458,12],[117,323],[-202,-25],[-330,112],[-85,-313],[-137,-124]],[[44579,66204],[106,168],[-637,-37],[97,304],[195,65],[-142,148]],[[37283,59533],[110,377],[264,153],[391,118],[356,386],[299,143],[406,475],[-84,294],[348,279],[83,181],[452,69],[518,181],[222,-53],[483,222],[201,12],[208,225],[316,83],[214,203],[294,83],[138,351],[-258,27],[50,220],[-391,340],[244,171],[-496,727],[385,181],[65,128],[917,529],[-140,348],[363,-7],[1338,225]],[[17122,61344],[-357,228],[103,148],[-1016,562],[187,128],[-241,174],[-86,-77],[-164,194],[-361,241],[498,450],[-304,222],[-48,152]],[[11105,60227],[-45,-174],[195,47],[377,-153],[128,129],[142,-137],[514,-254],[610,-597],[96,235],[293,415],[783,-372],[512,271],[136,365],[128,-4],[112,335],[156,155],[551,-396],[422,193],[207,244],[208,-56],[360,396],[-244,156],[376,319]],[[15333,63766],[-844,-914],[-174,76],[-448,-199],[-405,-463],[-264,8],[-470,-370],[-117,-159],[-54,-343],[-302,-107],[-151,-180],[-164,44],[-208,-422],[-180,74],[-335,-545],[-112,-39]],[[10944,52869],[-356,-10],[-250,-187],[-468,-169],[-302,261],[-436,-302],[-495,-186],[-154,74],[-71,329],[-168,-2],[-93,-235],[-233,134],[-102,-315],[-308,-213],[122,-57],[-291,-412],[-312,-120],[84,-247],[431,-153],[274,-274],[444,128],[507,-23],[100,98],[341,-100],[418,211],[270,-85],[797,165],[877,790],[107,152]],[[11677,52121],[-352,-104],[-431,-30],[369,169],[-215,204],[337,187],[-130,178],[-311,144]],[[38334,77143],[468,340],[396,-417],[522,389]],[[34591,78539],[186,-228],[411,160],[66,-58],[739,297],[-112,240],[534,147],[409,-573],[210,26],[449,-425],[851,-982]],[[33740,80543],[597,-564],[-510,-321],[328,-310],[303,-588],[-83,-74],[216,-147]],[[38047,82681],[-756,-673],[-381,236],[159,140],[-353,238],[-362,-319],[-95,245],[-1681,-1051],[288,-286],[-1126,-668]],[[39720,77455],[-179,158],[873,577],[86,-68],[847,737],[90,-61],[575,577],[-1106,868],[-952,702],[-500,402],[-268,274],[-686,508],[-453,552]],[[21307,68687],[458,868],[-291,5],[139,440],[142,-36],[39,217],[437,161],[143,208],[100,705],[-518,73],[125,860],[-351,-87],[-248,391],[-1302,-296],[-621,-265],[264,-449],[-1331,-544],[834,-357],[-196,-173],[522,-321]],[[19652,70087],[130,-80],[-362,-388],[503,-84],[4,-124],[651,-299],[192,-215],[537,-210]],[[11677,52121],[658,179],[881,69],[176,132],[296,-147],[377,50],[389,-289],[422,-98],[984,-638],[334,-308],[143,73],[751,-265],[811,-74],[408,-97],[322,-159],[134,210],[284,-104],[419,336],[120,227],[-394,162],[229,270],[-207,143],[103,236],[2527,2940],[-309,357],[-678,369],[197,347],[-388,254],[-311,51],[-453,167],[-657,716],[-213,17],[-95,153],[-206,-162],[-246,49],[-271,-246],[-179,227],[303,178],[95,462],[-460,241],[-137,175],[-25,332],[-392,275],[-309,4],[19,332],[-216,-165],[-434,18],[182,302],[-182,0],[-230,-644],[411,-28],[-458,-543],[-368,-255],[292,-126],[-763,-560],[-630,-279],[-761,-662],[-397,-206],[-176,-279],[353,-107],[-222,-139],[-82,-221],[-331,71],[94,-329],[-545,-395],[112,-122],[-332,-47],[-155,-411],[-232,-245],[-497,-375],[-244,-104],[197,-378],[-285,-212],[-286,43]],[[30923,79515],[144,-290],[-78,-128],[369,-193],[154,-414],[509,-123],[444,-720],[484,-240],[112,-282],[-301,-45],[251,-198],[288,131],[402,-602],[210,-212],[365,114],[720,-1068],[716,339],[-786,1034],[89,94],[-429,629],[-156,-15],[-327,266],[99,79],[-244,406],[390,180],[243,282]],[[33740,80543],[-1070,1020]],[[17122,61344],[151,-108],[1027,476],[530,-399],[94,61],[122,-300]],[[14439,65294],[-148,-81],[132,-227],[-478,-568],[465,-330],[193,183],[232,-173],[147,33],[351,-365]],[[19652,70087],[-260,-255],[-417,254],[-252,-242]],[[21786,68432],[-479,255]],[[38047,82681],[-443,301],[520,449],[-420,283],[901,804],[-307,405],[-692,303],[-333,78],[-128,141],[-218,-94],[-394,-305],[-138,130],[-282,-116],[-457,399],[-236,14],[-340,155],[-493,547],[-5205,4586],[-3372,-3269]],[[44198,66852],[616,153],[-387,113],[280,211],[249,-71],[20,350],[639,200],[-82,36],[618,231],[153,180],[398,177],[-61,204],[217,135],[560,-31],[487,73],[432,258],[261,357],[-38,250],[213,272],[-152,244],[246,151],[51,276],[-315,395],[-168,75],[244,83],[-31,252],[446,591],[-94,274],[160,87],[-46,151]],[[38334,77143],[432,-495],[-465,-421],[84,-56],[-616,-525],[-527,-345],[-364,-921],[566,-444],[-438,-537],[234,-298],[-238,-244],[9,-336],[399,-308],[-183,-223],[341,-221],[462,175],[659,-570],[-198,-124],[165,-124],[-388,-353],[-255,172],[-203,-213],[610,-468],[-159,-354],[288,-181],[708,-174],[72,-223],[-75,-265]],[[48360,73280],[-193,57],[-284,-571],[-356,-362],[59,-97],[-393,-371],[-520,251],[-337,-485],[-317,172],[-347,393],[-205,-162],[-430,540],[104,43],[-10,276],[281,147],[410,315],[-118,306],[234,187],[375,29],[288,169],[99,235],[-469,176],[-865,619],[-190,191],[186,153],[545,901],[199,143],[-189,223],[-364,279],[-282,-96],[-773,251],[-45,195],[-612,-193],[-481,488],[-311,235],[-144,-444],[-3,-253],[-174,124],[-367,-209],[-43,-199],[-285,21],[-204,-373],[-180,-29],[-568,142],[-203,-17],[-476,114],[-682,661]],[[49114,72529],[49,373],[-358,-34],[-617,354],[172,58]],[[6669,73710],[3656,-3303],[540,-429],[360,-161],[257,44],[41,-432],[527,-54],[264,175],[178,-102]],[[25714,68655],[156,154],[77,990],[501,767],[-60,35],[1617,1631],[1609,901],[-276,300],[-267,-69],[-461,869],[-281,-69],[-136,300],[-243,-57],[-333,488],[-329,-26],[-436,512],[-1328,-434],[-1248,-381],[-90,268],[-239,-101],[-37,159],[-347,334],[737,163],[299,198],[357,-120],[442,192],[221,164],[729,187],[333,-415],[752,283],[-111,131],[812,315],[-1584,1644],[-604,-350],[-251,303],[-264,-158],[-401,478],[-287,222],[-136,-96],[-164,195],[-139,-158],[-310,368],[-421,285],[-4035,4044],[-12869,-9391]],[[6381,62731],[112,-193],[324,-197],[956,-786],[172,-191],[756,-497],[303,294],[190,-129],[566,315],[658,-381],[54,40],[656,-613],[-23,-166]],[[11472,65750],[-765,-344],[-554,-197],[-142,102],[-603,-402],[-462,-258],[-429,-152],[-209,-178],[1,-157],[-1172,-653],[-626,-416],[154,-153],[-284,-211]],[[4731,55347],[-454,-704],[-119,-306],[-184,-196],[-495,-270],[-861,-671],[-138,-294],[-740,-74],[-233,-69],[-630,-833],[121,-301],[347,-332],[953,-385],[222,-200],[154,-327],[-270,-195],[337,-281],[-18,-161],[180,-125],[97,-247],[616,295],[44,-42],[643,316],[1067,954],[-171,100],[165,161],[-81,193],[140,216],[428,333],[366,200],[19,174],[259,254],[-177,95],[192,294],[-60,210],[140,1226],[210,318],[-270,172],[-254,38],[-633,419],[-430,-305],[-482,350]],[[12926,68179],[-32,-195],[697,-135],[-193,-60],[141,-276]],[[6669,73710],[-6669,-4866],[3950,-3385],[766,-557],[155,-165],[578,-408],[287,-329],[321,131],[422,261],[582,-571],[-96,-212],[-1278,-785],[-415,-725],[178,-114],[931,746]],[[23653,42445],[224,356],[580,652],[427,348],[181,-155],[299,361],[-162,92],[166,461],[218,-37],[415,430],[-248,55],[-398,376],[-299,84],[-333,385],[-562,262],[-610,55]],[[20089,41506],[318,436],[886,49],[-96,-113],[779,-258],[271,148],[235,-42],[170,183],[467,305],[534,231]],[[23551,46170],[-304,-422],[6,-243],[-321,-384],[-265,80],[-282,-446],[-167,-10],[-219,-300],[-397,19],[-950,-940],[-325,-247],[-376,276],[-361,151],[-297,-189],[-229,-424],[36,-168],[-404,-42],[188,-724],[276,-208],[381,-153],[121,26],[427,-316]],[[42256,39727],[-64,91],[398,437],[131,583],[-318,205],[458,140],[105,393],[375,168],[325,378]],[[40482,38756],[363,11],[3,329],[119,163],[642,194],[417,37],[328,-54],[-98,291]],[[35606,43492],[-266,-610],[147,-163],[-129,-109],[-140,-360],[108,-230],[216,-123],[255,18],[364,-141],[655,10],[398,-329],[-46,-367],[138,-113],[11,-303],[224,-85],[441,194],[247,-65],[195,-167],[-12,-207],[242,-320],[505,-166],[67,-159],[398,-50],[53,-215],[389,-80],[305,-337],[111,-259]],[[39354,44185],[-350,172],[-661,63],[-144,-377],[-274,-180],[-169,55],[-131,-265],[-576,315],[-396,-20],[-465,-606],[-582,150]],[[43666,42122],[-504,135],[-438,186],[-209,-27],[-482,214],[-516,20],[-464,265],[-376,278],[-72,132],[-389,210],[-500,554],[-202,-45],[-160,141]],[[34433,55290],[-217,278],[-617,482],[-296,26],[437,374],[-197,13],[-290,164],[-274,-195],[-872,538],[-528,144],[-312,159],[-1071,168],[-233,335],[-690,158],[-72,103]],[[30215,52007],[797,-128],[399,134],[20,274],[-97,111],[494,660],[508,394],[461,222],[-52,66],[852,528],[642,554],[-96,74],[290,394]],[[29201,58037],[-238,-215],[-686,-739],[-451,-376],[-474,227],[164,103],[-106,148],[-144,-101],[-327,132],[-381,-243],[-447,-450],[-151,-271],[373,-211],[-262,-220],[244,-267],[201,232],[458,-235],[305,236],[459,-449],[60,-137],[671,160],[387,191],[545,155],[105,-32],[315,-366],[325,-258],[465,-186],[9,-172],[237,-491],[241,-102],[-252,-621],[-504,-564],[-68,-302],[-146,-135],[247,-263],[-160,-208]],[[38874,38322],[651,49],[694,277]],[[34573,44146],[-332,-221],[-72,-316],[-549,-500],[7,-464],[-257,2],[-36,-352],[-341,-277],[552,-403],[559,-299],[116,-140],[373,248],[229,-286],[560,306],[-18,-223],[148,-336],[230,-193],[716,-98],[213,-92],[173,-340],[18,-246],[563,-292],[232,-45],[239,139],[231,-321],[151,7],[181,-276],[-408,-138],[373,-278],[519,-227],[-69,-163]],[[35606,43492],[-571,233],[109,170],[-571,251]],[[40219,38648],[263,108]],[[34353,47037],[-265,-377],[704,-198],[-92,-435],[-129,-167],[109,-103],[-155,-127],[90,-512],[-147,-186]],[[37323,47919],[-208,-145],[-180,97],[-344,-63],[94,-194],[-342,-77],[-109,-127],[-263,108],[-364,-153],[-85,-436],[-276,116],[-254,-26],[-245,104],[-227,-174],[-167,88]],[[39354,44185],[-189,449],[-304,342],[184,114],[-197,33],[-730,575],[248,151],[-280,517],[143,92],[-457,395],[-17,206],[-207,154],[321,381],[-546,325]],[[34468,44932],[285,15],[182,-155],[-195,-258],[-208,-89],[-185,-230],[226,-69]],[[28625,40315],[375,-40],[5,386],[400,-290],[608,354],[-50,48],[516,404],[290,105],[235,189],[296,404],[408,753],[419,1176],[470,223],[146,-58],[565,72],[223,207],[301,530],[217,14],[17,267],[139,44],[263,-171]],[[26135,41739],[71,-139],[-439,-635],[317,-317],[505,-175],[528,-89],[354,-268],[399,-34],[366,293],[258,61],[131,-121]],[[33954,47471],[-101,-115],[-193,128],[-734,-748],[-332,-170],[-833,-715],[-80,-299],[-234,-202],[-551,64],[-206,-56],[-641,-530],[-166,-276],[-302,329],[-389,109],[-473,241],[-199,2],[-384,-374],[-509,-605],[-68,35],[-303,-458],[-85,-343],[-116,-1],[-462,-518],[-184,-540],[-252,-138],[152,-255],[-174,-297]],[[34353,47037],[173,226],[-341,278],[-231,-70]],[[33954,47471],[-192,118],[198,212],[108,419],[-280,-197],[-817,-410],[-475,-200],[-702,-455],[-114,-135],[-666,-131],[-320,372],[-392,-64],[-207,432],[-231,-34],[-15,144],[-537,364],[-144,444],[-243,46],[93,190],[-211,46],[-101,516],[159,70],[-90,233],[427,184],[-587,491],[-525,190]],[[23653,42445],[-12,-266],[189,-147],[-253,-236],[374,-54],[451,-182],[294,578],[389,-182],[-76,-80],[600,-211],[190,-5],[44,197],[292,-118]],[[28090,50316],[-340,-522],[-96,39],[-264,-366],[-195,235],[-189,-251],[-614,-120],[-641,-503],[-559,-285],[-750,-658],[-394,-576],[-339,-138],[-336,-521],[322,-223],[-144,-257]],[[16518,28864],[-297,4],[176,228],[-104,278],[-254,89],[-498,366],[257,150],[189,485],[375,275],[83,-86],[268,255],[106,374],[-393,303],[-898,10],[-249,79],[73,314],[-465,122],[96,234],[-272,8],[26,511],[234,162],[-46,479],[-142,45],[-575,-159],[-850,56],[-379,91],[-202,-48],[-223,145],[98,195],[-274,638],[-308,170],[-329,-8],[-195,-191],[-540,-348],[-418,52],[-143,-381],[-384,-2],[56,293],[-226,438],[402,418],[144,446],[-186,148],[-37,342],[-236,194],[-75,344],[-587,158]],[[15295,25502],[-121,50],[202,356],[189,42],[-40,383],[-107,136],[122,164],[-189,268],[335,341],[353,631],[74,395],[333,370],[72,226]],[[9316,36540],[-46,-159],[-235,79],[-240,-508],[-204,-301],[-125,-694],[-88,-15],[-117,-424],[223,-527],[323,-45],[32,-261],[255,-122],[-54,-471],[230,-476],[-168,-633],[80,-436],[-179,-129],[182,-493],[49,-469],[80,-124],[-323,-1522],[-570,-150],[282,-1101],[161,-198],[-214,-325],[1,-343],[-228,-466],[152,-80],[-91,-169],[-1,-453],[-217,-305],[-230,-168],[16,-363],[-236,-327],[390,-173],[348,-70],[486,146],[129,344],[142,-42],[102,226],[479,-59],[231,217],[227,19],[374,-132],[-258,509],[245,395],[160,84],[6,320],[1076,-419],[176,-574],[90,-9],[156,-449],[493,83],[297,-140],[82,-143],[877,-187],[414,261],[-80,122],[454,250],[383,561]],[[21467,32837],[357,25],[189,358],[526,-196],[66,32]],[[17200,38391],[-20,-175],[-388,-343],[232,-895],[165,-196],[287,-144],[221,155],[514,-283],[-137,-300],[793,-398],[-189,-296],[-157,-67],[-121,-337],[-26,-482],[204,-507],[-67,-560],[714,-143],[-110,-257],[-127,25],[-98,-390],[619,29],[475,-229],[148,105],[662,80],[181,-122],[492,176]],[[20089,41506],[-270,-234],[-448,-523],[-71,-180],[-375,-550],[616,-320],[-171,-149],[116,-238],[-338,-319],[-450,-95],[-568,278],[-118,-178],[-289,-157],[-25,-117],[-498,-333]],[[22605,33056],[649,515],[372,-78],[255,516],[-106,241],[-223,178],[-571,55],[17,514],[118,209],[438,-77],[289,565],[555,65],[409,259],[323,587],[241,243],[438,296],[186,-130],[158,-329],[707,-205],[455,303],[78,314],[273,337],[-269,262],[110,222],[-129,60],[382,726],[206,-151],[285,341],[283,526],[-146,206],[97,484],[140,205]],[[16518,28864],[639,-126],[203,252],[186,651],[296,373],[413,228],[181,-222],[153,320],[250,253],[414,-189],[223,393],[-7,163],[476,-378],[225,-16],[184,207],[556,1006],[-255,55],[-98,181],[262,389],[164,-46],[329,91],[-49,140],[229,79],[-25,169]],[[17200,38391],[-1300,523],[-152,-123],[-327,205],[310,351],[-307,1],[-54,135],[-538,174],[-333,-192],[-452,136],[-318,-421],[-388,131],[-238,-128],[-238,-263],[-802,-1143],[-570,-447],[189,-254],[-618,-54],[-176,364],[-236,-56],[-203,165],[-558,83],[-337,-78],[-460,-215],[-485,52],[-27,-240],[287,-220],[477,-161],[-30,-176]],[[31030,31565],[533,299],[144,-259],[257,-106],[319,175],[215,303],[71,297],[-396,332],[-116,191],[373,362],[-412,303],[-11,164],[349,493],[87,248],[-221,28],[-24,413],[-280,304],[-247,84],[146,92],[-338,366],[-71,255],[176,11],[45,164],[227,136],[-161,147],[41,218],[149,29],[-298,229],[260,200],[-48,307],[100,94],[15,340],[298,570],[246,21],[393,-155],[121,89],[259,-66],[97,322],[184,-3],[178,-157],[335,228],[-68,147],[659,336],[4,151],[555,95],[684,-240],[328,138],[232,184],[240,-139],[480,-646],[326,-313],[448,292],[407,-197],[554,-119]],[[25580,31260],[558,228],[80,-148],[709,193],[116,189],[248,-4],[686,190],[708,-249],[377,-386],[194,146],[357,-178],[282,13],[-16,-249],[261,191],[890,369]],[[22605,33056],[-83,-290],[709,21],[168,-38],[391,118],[206,-175],[-54,-161],[345,-234],[99,-269],[294,-160],[55,-148],[291,-207],[413,-115],[141,-138]],[[41346,51042],[122,119],[-262,61],[-44,173],[257,135],[209,-61],[135,179],[-405,230]],[[46655,43350],[-101,129],[-301,-6],[-552,353],[-182,336],[-259,202],[-324,-29],[-423,382],[-330,399],[-556,-112],[70,418],[-113,110],[22,325],[-267,536],[-262,342],[-339,226],[-213,-105],[-580,-80],[-227,325],[157,143],[-264,184],[-187,433],[-215,114],[-191,514],[-65,474],[316,154],[-43,125],[430,217],[276,72],[-30,172],[385,70],[39,162],[-417,765],[-596,106],[33,236]],[[43666,42122],[486,178],[248,181],[337,122],[1083,503],[273,45],[562,199]],[[38769,52629],[-222,-64],[-233,80],[-346,-109],[-327,-231],[-628,-82],[-111,-138],[-396,-157],[-52,-132],[-602,-299],[-268,-387],[51,-170],[-182,-197],[179,-386],[-276,-543],[356,-227],[259,-784],[227,184],[156,-24],[313,306],[487,-129],[-239,-308],[278,-302],[-143,-256],[383,-173],[-110,-182]],[[41358,51878],[-503,71],[-193,-82],[38,-152],[-394,-82],[-211,181],[-223,451],[-387,-81],[-410,192],[-114,284],[-192,-31]],[[33912,62035],[-225,-101],[54,-251],[-142,-174],[-365,-111],[-441,-255],[-227,-426],[-399,46],[-280,263],[-622,-169],[-390,-475],[-194,74],[-157,-460],[-484,-355],[-74,60],[-321,-282],[236,-111],[-290,-384],[310,-93],[121,114],[206,-181],[-645,-341],[-382,-386]],[[37144,56378],[-192,37],[-231,530],[63,204],[-353,125],[-126,164],[664,493],[-184,238],[278,141],[-131,348],[273,228],[-114,186],[160,175],[32,286]],[[36954,55707],[311,588],[-121,83]],[[34433,55290],[146,-103],[207,142],[75,-108],[652,282],[73,-39],[344,366],[210,-240],[287,-143],[527,260]],[[37253,55077],[-284,113],[255,214],[-20,146],[-250,157]],[[38769,52629],[-84,467],[-412,93],[-605,338],[-473,601],[-239,163],[207,246],[-275,254],[365,286]],[[30215,52007],[-819,-532],[-889,-811],[-417,-348]],[[40224,16913],[227,-445],[405,-354],[-336,-344],[-253,-77],[-83,-365],[3,-340],[-105,-137],[-38,-530],[-245,-353],[376,-718],[23,-490],[186,-62],[123,-433],[-258,-218],[-264,-58],[-433,-210],[-211,-178],[-385,-166],[-295,-232],[-98,-551],[170,-542],[65,-586],[-435,-757],[-270,-290],[5,-410],[-103,-267],[-627,-680],[-319,-522]],[[41781,18963],[-455,-232],[-156,-294],[66,-207],[-353,-317],[-115,-248],[98,-128],[-92,-193],[-550,-431]],[[45465,18602],[-284,-119],[-285,-241],[-349,-192],[-259,0],[-76,228],[-428,219],[-250,-28],[-118,372],[-460,133],[-772,29],[-403,-40]],[[50766,17204],[-181,69],[-986,114],[-706,23],[-577,62],[-294,169],[104,208],[-414,179],[-218,-80],[-287,58],[6,187],[-495,-139],[-625,-53],[-250,287],[-378,314]],[[57309,9854],[-872,535],[-128,133],[-707,241],[-28,299],[200,620],[-339,-62],[-348,50],[-166,123],[-153,318],[602,522],[419,693],[-557,251],[-685,415],[298,615],[-72,395],[-693,142],[-995,290],[-309,131],[-137,183],[-385,180],[-29,161],[-324,-360],[-334,200],[225,314],[-308,114],[-223,-284],[-114,14],[-283,-376],[-304,73],[66,329],[-59,740],[199,351]],[[37049,6598],[-456,-289],[-99,-148],[169,-446],[-117,-511],[117,-127],[-52,-412],[48,-530],[236,-443],[349,5],[261,-369],[838,-700],[184,-258],[189,-459],[-318,-368],[-302,-479],[-560,-602],[-175,-316],[51,-130],[555,-13],[848,163],[380,151],[154,145],[456,166],[544,333],[889,250],[637,293],[799,236],[102,-151],[315,966],[226,1061],[-150,150],[390,404],[345,277],[302,147],[269,464],[1595,1314],[558,305],[320,90],[584,419],[135,218],[368,281],[554,160],[738,434],[318,359],[748,308],[661,-363],[373,-105],[821,425],[762,-189],[714,0],[306,-152],[605,93],[360,104],[474,58],[369,-251],[415,152],[501,416],[84,350],[285,110],[188,260]],[[47138,43645],[336,-471],[300,-183],[779,37],[525,-139],[351,-159],[380,-323],[160,-335],[379,-121],[245,-211],[177,-37],[515,-324],[125,-179],[585,-7],[141,65],[285,-77],[-331,-952]],[[55235,47378],[-736,568],[-439,-202],[-563,-30],[-485,-98],[127,-166],[-62,-289],[-649,-106],[-18,-222],[247,-413],[-754,-159],[-245,52],[-294,-357],[-388,-66],[-255,-228],[-207,-416],[-706,-701],[-630,-31],[-260,91],[-1121,224],[24,-389],[-243,-485],[-440,-310]],[[56888,43742],[166,271],[-34,455],[326,185],[-29,92],[-427,295],[-702,-427],[-491,361],[-611,188],[-82,193],[198,142],[461,157],[347,-253],[419,64],[107,221],[-509,260],[-377,383],[36,595],[-285,105],[-232,223],[66,126]],[[55094,41387],[212,867],[347,464],[466,204],[373,327],[396,493]],[[52090,40229],[-81,-168],[620,176],[410,19],[130,-199],[260,-89],[342,246],[548,728],[339,336],[-42,94],[363,98],[115,-83]],[[55747,34768],[693,-575],[114,-1697],[-203,-1904]],[[61431,34356],[-2080,327],[-1993,63],[-1018,-6],[-593,28]],[[61082,33800],[7,260],[342,296]],[[58520,30506],[-32,386],[383,144],[105,160],[579,442],[56,190],[-186,179],[188,244],[-202,98],[499,399],[171,41],[36,384],[-77,105],[133,219],[595,237],[314,66]],[[56351,30592],[613,-139],[684,-206],[266,-198],[392,-9],[-51,165],[265,301]],[[61506,30645],[-437,-38],[-240,62],[-293,-89],[-66,-303],[-339,-134],[-260,13],[-737,-197],[-206,1],[-126,494],[-282,52]],[[62134,30495],[-628,150]],[[64465,28653],[-179,343],[-294,188],[-163,361],[-436,140],[-455,55],[-804,755]],[[54812,29110],[149,-803],[255,-634],[448,-708],[204,-442],[-8,-239],[1026,-437],[1164,199],[241,2],[637,160],[304,-34],[237,101],[778,153],[822,301],[751,368],[296,282],[907,569],[280,297],[416,103],[746,305]],[[54973,31019],[-111,-267],[-244,-279],[-139,-278],[132,-200],[493,-151],[30,-122],[-309,-349],[-13,-263]],[[56351,30592],[-1197,445],[-181,-18]],[[52552,34686],[-149,-336],[-440,-446],[-459,311],[-37,-38],[-894,465],[-484,-185],[-322,73],[6,-140],[-486,156],[-526,-2],[-449,-99],[102,89],[-627,318],[-215,-109],[-254,63],[-481,345],[-370,423],[-67,-63],[-405,115],[-441,-376],[-543,-355],[99,-316]],[[53405,34413],[-187,226],[-347,102],[-319,-55]],[[54973,31019],[-509,-29],[-117,-70],[-526,201],[91,266],[-212,514],[-218,-127],[-173,-383],[-383,-39],[-208,125],[-318,9],[-317,238],[326,304],[-134,79],[186,154],[-122,311],[269,252],[-150,329],[139,206],[-181,47],[115,157],[-186,129],[709,428],[-19,148],[370,145]],[[51009,27300],[769,474],[127,367],[196,84],[390,-593],[184,-104],[305,272],[-224,122],[-94,236],[232,149],[131,496],[355,-41],[395,114],[267,250],[475,-177],[295,161]],[[46330,24329],[-264,-24],[-411,202],[63,449],[898,369],[-178,242],[560,426],[275,10],[230,128],[-128,163],[46,201],[174,92],[-185,204],[-669,478],[-290,449],[-37,388],[-176,166],[-221,537],[-193,257],[-336,159],[-135,208],[412,470],[766,491],[499,84],[-161,-383],[-434,-192],[273,-1134],[339,-392],[-45,-167],[381,-84],[628,521],[178,51],[577,445],[189,-180],[-273,-160],[47,-192],[407,-300],[83,-206],[223,263],[-5,-279],[371,345],[597,-437],[54,-194],[204,-144],[-314,-175],[514,-35],[146,-149]],[[40612,23958],[83,418],[-27,269],[375,151],[-42,500],[-112,46],[132,212],[540,178],[356,-66],[81,390],[201,132],[-25,258],[538,679],[-382,102],[128,276],[-198,162],[69,434],[191,332],[249,-14],[540,223],[91,137],[233,36],[162,-233],[117,-1161],[240,-680],[208,-753],[-176,-484],[227,-448],[-295,-559],[-371,-129],[-495,-305],[-187,-431],[195,-348],[652,-9],[130,-138],[222,204],[655,285],[-82,143],[175,137],[471,-50],[849,475]],[[45493,33535],[479,-453],[-638,-334],[34,-206],[308,-267],[-409,13],[177,-381],[394,119],[241,-408],[-489,-133],[22,-163],[315,59],[-36,-450],[-346,34],[-47,-279],[-150,-184],[-552,-374],[-407,243],[-253,61],[-673,-184],[-495,-66],[-556,-274],[176,-219],[-361,-155],[-77,-358],[-571,56],[-470,-84],[-446,-512],[-153,-459],[-235,-306],[-196,-390],[-199,-147],[-159,-265],[-105,-545],[71,-44],[-89,-400],[-117,-61],[-388,-450],[301,-382],[402,-717],[577,-241],[239,-271]],[[45110,34579],[93,-258],[229,-187],[340,-54],[-210,-174],[171,-155],[-240,-216]],[[61253,33760],[-171,40]],[[61506,30645],[365,310],[48,148],[-237,464],[-354,115],[-111,331],[163,230],[-19,209],[-161,114],[8,214],[-410,343],[197,24],[258,613]],[[54153,39148],[46,-235],[476,-83],[279,-148],[222,80],[199,-1263],[-278,-941],[220,-939],[430,-851]],[[55765,40631],[-398,-215],[149,-234],[-155,-45],[-226,-290],[-75,31],[-318,-330],[-465,-200],[-124,-200]],[[63380,37750],[-292,332],[-551,292],[-620,197],[-711,-56],[-467,167],[-333,10],[-342,219],[-829,354],[-296,390],[-451,-201],[-143,90],[-332,-49],[-834,18],[-669,194],[-708,569],[-37,355]],[[61431,34356],[102,150],[-111,269],[53,157],[469,403],[327,141],[175,162],[-3,285],[648,239],[279,49],[-375,835],[168,185],[217,519]],[[62134,30495],[161,53],[15,396],[83,139],[800,482],[340,163],[56,198],[376,41],[-228,285],[75,193],[254,104],[-72,144],[263,250],[-286,-32],[-331,234],[31,264],[-375,-20],[-582,-115],[-475,328],[-22,118],[-428,-65],[-536,105]],[[53405,34413],[891,330],[404,79],[1047,-54]],[[50568,37215],[-298,-271],[511,-212],[-79,-116],[258,-117],[-58,-151],[795,-658],[-106,-133],[598,-301],[-148,-220],[344,-65],[167,-285]],[[54153,39148],[-851,-67],[-382,-142],[-194,-312],[-59,-363],[-300,-455],[-282,14],[-448,172],[-308,-532],[-121,-117],[-390,155],[-250,-286]],[[45036,33465],[457,70]],[[45110,34579],[-146,37],[-380,-136],[-281,197],[-572,-350],[176,-29],[86,-339],[188,-265],[418,-27],[437,-202]],[[57309,9854],[468,172],[869,385],[736,204],[596,716],[-31,67],[730,262],[696,519],[142,174],[133,791],[1047,1582],[215,836],[320,109],[208,171]],[[63227,16880],[-985,329],[630,1125],[-1426,0],[-254,-460],[-451,127],[-184,265],[-85,320],[-378,407],[-207,22],[-519,-131],[-416,252],[-698,225],[-468,215],[-228,298],[-135,-76],[-739,64],[-648,318],[237,308],[-491,140],[69,200],[-633,-35],[-287,-114],[-287,55],[-806,450],[-772,-748],[-320,-518],[-244,-763],[-311,-456],[-466,-414],[-402,-635],[-557,-446]],[[63438,15842],[-16,377],[-161,328],[-34,333]],[[45465,18602],[494,308],[663,577],[-341,433],[-340,237],[467,340],[309,31],[320,275],[-159,131],[-163,376],[-138,106],[74,270],[139,123],[152,364],[174,198],[530,413],[545,-125],[-15,171],[573,278],[244,49],[301,282],[221,-86],[340,73],[222,-37],[268,125],[643,190],[149,192],[214,-158],[392,163],[521,33],[431,199],[269,208],[845,-192],[-25,-179],[1062,-206],[318,343],[572,-30],[734,189],[332,398],[657,370],[728,88],[249,126],[660,60],[573,236],[551,-27],[386,218],[880,-88],[309,93],[507,33],[310,144],[681,145],[939,365],[128,100],[1260,309]],[[40117,23864],[-260,-114],[-192,-249],[-810,-651],[-47,-203],[-445,-324],[-179,-233],[-280,-160],[-164,-285],[5,-369],[-341,-306],[-177,-389],[128,-203],[295,-131],[1031,-224],[747,254],[2353,-1314]],[[40225,23941],[-108,-77]],[[40612,23958],[-387,-17]],[[51009,27300],[-242,-331],[27,-163],[-305,-238],[158,-113],[-312,-206],[111,-109],[-71,-272],[-497,-136],[-122,-210],[-607,-97],[-151,-178],[-72,-324],[-218,-25],[-250,103],[-1064,-199],[-703,-265],[-361,-208]],[[65620,26836],[-456,710],[-164,107],[-287,749],[-248,251]],[[63380,37750],[253,31],[37,152],[354,300],[-30,386],[773,537],[461,-274],[486,-2],[491,-306],[447,-145],[-157,339],[73,194],[787,209],[296,493],[206,679],[4,298],[-93,124]],[[55094,41387],[105,-232],[371,-289],[195,-235]],[[58714,43672],[-195,-157],[-396,-55],[-209,78],[-620,78],[-406,126]],[[67768,40765],[-992,75],[-1029,-106],[-278,-279],[-1016,362],[-1226,476],[-847,715],[-447,143],[-520,310],[-267,31],[-989,380],[-149,120],[-648,279],[-646,401]],[[81011,21949],[645,723],[444,712],[721,860],[426,391],[402,202],[105,198],[667,553],[363,-58],[610,-227],[220,-139],[1470,-442],[143,-19],[681,111],[712,277],[437,736],[268,646],[411,213],[885,258],[-925,1507],[220,1567],[312,1198],[-49,428],[-904,554],[60,1543],[127,1082]],[[83936,39096],[338,-96],[308,-328],[-291,-217],[86,-380],[505,-91],[113,-327],[215,-132],[52,-570],[-642,-477],[-137,-199],[-8,-337],[-172,-285],[-361,-224],[-212,-20],[-285,-297],[7,-248],[-422,-221],[-191,-400],[-468,-322],[121,-306],[-1013,-639],[-45,-81],[-478,26],[-315,-57],[-160,-171],[-438,-281],[-289,-70],[-986,40],[-391,110],[-578,-174],[109,-240],[-74,-203],[230,-380],[-462,-216],[-439,-284],[-175,-252],[-602,-265],[-224,13],[-72,-152],[-466,-314],[-1552,-1237],[-261,-385],[-379,258],[-1304,338],[39,-130],[-224,-184],[-148,-253],[128,-506],[-265,-273],[-273,-1128],[56,-201],[-105,-632],[-113,-166],[-280,-161],[-193,19],[-88,-157],[175,-445],[-178,-273],[17,-600],[236,-550],[25,-532],[-139,-179],[87,-259],[2431,150],[259,369],[354,277],[461,480],[38,190],[324,306],[799,142],[683,171],[208,118],[87,-95],[-228,-298],[139,-314],[428,-25],[860,-656],[835,-444],[563,-223],[1885,-592]],[[89462,34823],[-380,-127],[-379,-28],[-665,448],[-35,280],[-153,169],[151,175],[713,399],[1020,860],[88,303],[422,240],[-662,432],[-553,305],[-211,172],[-711,290],[-91,436],[-256,117],[-250,225],[-342,149],[-156,367],[-790,673],[-777,-208],[-423,-27],[-719,-573],[-81,-482],[-286,-322]],[[52090,40229],[-188,-42],[-62,-187],[-287,115],[-325,-139],[90,-71],[-486,-96],[-122,-106],[-409,-114],[-210,98],[-234,-179],[-179,21],[-617,-206],[141,-254],[-339,60],[-620,-21],[-109,129],[-392,173],[-527,-7],[-83,93],[-469,49],[-517,-198],[-903,-172],[-519,-172],[45,447],[-348,131],[-244,376],[-586,-305],[-513,-173],[15,-165],[-321,-74],[-310,456],[-206,31]],[[41957,37710],[435,139],[778,-64],[492,-92],[72,53],[890,-245],[283,-227],[349,-5],[791,169],[398,181],[767,-99],[393,-107],[858,-140],[406,-11],[456,-234],[156,171],[404,-178],[341,338],[342,-144]],[[40219,38648],[116,-203],[477,25],[82,-144],[435,156],[245,-169],[75,-342],[168,44],[140,-305]],[[58714,43672],[246,180],[83,296],[-103,94],[164,266],[171,104],[-98,127],[-118,572],[315,179],[-10,101],[389,679],[190,167],[-133,245],[98,459],[-76,220],[-197,147],[70,425],[263,454],[498,337]],[[58202,49656],[-74,-249],[-378,-358],[-513,-243],[-187,-228],[-264,-721],[-327,15],[-192,104],[-265,-50],[-50,-181],[-253,-237],[-464,-130]],[[60466,48724],[-288,-6],[-148,96],[-585,-150],[-308,288],[-299,83],[-79,199],[-254,273],[-303,149]],[[43443,33707],[244,-500],[708,160],[240,-114],[401,212]],[[42275,35762],[456,-333],[86,35],[431,-330],[349,-86],[-185,-313],[81,-260],[-332,-243],[282,-525]],[[41957,37710],[215,-374],[9,-305],[336,-185],[-144,-319],[228,-94],[-192,-141],[-271,-367],[137,-163]],[[70535,46142],[-1105,425],[-461,-133],[-619,893],[-922,245],[-164,105],[-984,277],[-785,296],[-283,-12],[-408,254],[78,175],[-503,59],[-114,-245],[-1038,332],[-389,-163],[-202,25],[-207,-200],[-612,-23],[-532,117],[-403,153],[-416,2]],[[70583,46208],[-48,-66]],[[74317,45234],[-316,192],[-727,81],[-321,95],[-454,299],[-463,48],[-311,-71],[-495,-6],[-391,156],[-256,180]],[[67768,40765],[483,431],[229,55],[473,398],[1722,1009],[873,215],[99,560],[300,157],[249,266],[318,135],[1061,191],[609,191],[-50,619],[183,242]],[[34304,29432],[10,47],[-500,599],[-107,-82],[-544,392],[1123,607],[201,231],[627,502],[-329,355],[543,454],[907,468],[49,-101],[462,86],[640,460],[335,102],[128,-157],[177,10],[75,176],[973,530],[274,90],[452,-55],[362,136],[583,347],[373,77],[345,150],[245,381],[567,525]],[[32616,28793],[256,122],[605,105],[827,412]],[[31030,31565],[331,-305],[610,-884],[203,-603],[128,-548],[314,-432]],[[47138,43645],[-483,-295]],[[40225,23941],[-106,142],[-418,199],[-422,308],[-943,913],[-165,87],[-351,415],[-367,223],[111,106],[-85,543],[-150,297],[-44,528],[42,599],[-127,197],[-30,281],[235,209],[-189,325],[-85,379],[-172,106],[89,594],[-155,93],[233,202],[431,97],[452,188],[296,-31],[146,91],[211,339],[381,185],[242,-41],[627,15],[-35,110],[221,258],[1266,274],[-57,209],[298,47],[429,592],[342,-6],[235,196],[-61,112],[353,256],[540,129]],[[34304,29432],[184,-515],[321,-280],[787,-1043],[549,-502],[195,-283],[119,-379],[537,-919],[531,-409],[917,-395],[389,-260],[443,-108],[426,-195],[415,-280]],[[63227,16880],[240,298],[788,312],[644,543],[268,76],[290,387],[190,105],[377,391],[345,144],[-543,318],[-291,230],[-163,259],[-919,684],[144,175],[182,-66],[-223,424],[-235,114],[-148,294],[-201,58],[-304,396],[406,292],[209,588],[207,177],[94,254],[246,246],[114,450],[-4,270],[713,618],[93,330],[157,143],[9,257],[-425,466],[140,393],[-7,330]],[[80176,40961],[-54,114],[-497,119],[-537,404],[-117,334],[-56,494],[80,158],[-68,430],[259,272],[577,732],[30,142],[-206,155],[-49,271],[-191,53],[-227,358],[73,163],[-325,241],[-14,266],[-198,29],[-156,454],[-221,159],[23,357],[-336,390],[-83,503],[-262,201],[-791,-321],[-259,-226],[-496,-106],[-191,-133],[-199,-286],[-341,-55],[-278,-133],[-158,-332],[-314,-215],[9,-370],[-286,-349]],[[83936,39096],[-292,-211],[-288,39],[-234,310],[-280,89],[-583,-30],[-731,365],[-311,294],[-162,-18],[-193,166],[-316,466],[-370,395]],[[63438,15842],[713,-204],[475,17],[291,-106],[213,28],[684,271],[581,446],[677,327],[228,67],[636,451],[624,368],[240,64],[789,740],[525,402],[242,295],[196,-75],[1161,-785],[40,-298],[1031,-1251],[358,219],[381,460],[383,302],[673,780],[426,328],[135,381],[475,404],[838,354],[158,-35],[702,522],[120,-49],[535,78],[1037,348],[435,261],[520,201],[312,179],[554,423],[185,194]],[[40797,55337],[330,-428],[458,-434],[368,-934],[229,17],[159,-736],[-278,-245],[214,-360],[-930,-231],[11,-108]],[[42787,55718],[-553,-66],[-218,-145],[-394,223],[-325,1],[-299,-149],[-201,-245]],[[49186,54536],[-624,-25],[-783,-417],[-598,-272],[-369,207],[-610,-321],[-300,-52],[-169,210],[-765,-94],[-676,141],[-505,-53],[-222,297],[183,49],[-183,582],[-387,430],[-161,-42],[-180,232],[-50,310]],[[41346,51042],[611,107],[329,-126],[97,62],[661,-3],[291,107],[417,295],[56,-205],[358,34],[272,239],[65,-228],[258,41],[90,211],[557,-37],[6,-152],[235,118],[481,-193],[322,205],[7,182],[260,151],[470,398],[515,-94],[388,-131],[250,315],[309,101],[-72,273],[339,407],[-69,269],[52,255],[387,290],[15,197],[-280,227],[163,179]],[[49574,59607],[739,245],[509,-76],[478,44]],[[46030,61082],[138,-398],[333,-239],[510,97],[64,-288],[-206,-37],[45,-221],[274,49],[68,-114],[1378,491],[501,-638],[391,-84],[48,-93]],[[50970,63352],[-233,-253],[-391,-38],[-334,-224],[-552,-260],[-574,-123],[-228,17],[-1492,330],[-110,-61],[-708,-25],[53,-364],[-109,-713],[74,-177],[-336,-379]],[[53455,61453],[-80,238],[-157,15],[-149,679],[-198,-3],[-251,260],[-97,466],[-329,187],[144,137],[363,0],[189,229],[160,466],[-331,-47],[-316,-205],[20,-102],[-645,-126],[-71,157],[-533,-248],[-204,-204]],[[51300,59820],[474,248],[101,666],[856,233],[494,392],[230,94]],[[50785,65066],[557,97],[517,171],[1243,215],[351,-81],[248,181],[84,399],[104,62],[283,-206],[832,61],[333,259],[510,23],[369,101],[485,-102],[596,96],[346,-102],[366,139]],[[52067,71111],[686,-703],[250,-205],[392,-536],[118,-287],[321,-305],[-35,-274],[-271,-262],[-724,-307],[-153,-191],[-296,-143],[-980,-211],[102,-184],[-370,-274],[-9,-270],[185,-217],[-490,-314],[-700,-233],[-10,-143],[234,-338],[313,-70],[-14,-455],[169,-123]],[[55670,71368],[-533,-179],[-35,223],[189,161],[-226,23],[-196,222],[-328,214],[-432,-31],[-162,276],[-1252,-544],[39,-264],[-459,-142],[-208,-216]],[[59225,67209],[-153,195],[181,92],[-192,83],[-517,478],[203,105],[-278,203],[-226,14],[-231,152],[-539,-112],[-84,91],[-471,-249],[-451,405],[-107,335],[-227,250],[97,269],[-262,24],[8,295],[-683,-148],[-38,470],[576,175],[92,196],[-302,478],[262,16],[-213,342]],[[58009,66379],[508,230],[459,289],[249,311]],[[40797,55337],[-511,-313],[-214,181],[-391,-213],[-244,237],[-258,-101],[-314,307],[-123,-55],[-336,222],[-174,-158],[-385,-75],[-594,-292]],[[58337,64196],[-331,681],[365,39],[76,162],[-157,407],[237,47],[-103,369],[-244,-59],[-15,310],[-156,227]],[[56790,62312],[491,601],[60,764],[142,190],[438,202],[416,127]],[[53455,61453],[682,40],[357,-88],[-6,212],[442,68],[795,307],[-138,368],[470,297],[578,192],[94,-544],[61,7]],[[50825,64890],[-202,-324],[40,-221],[310,-190],[-168,-256],[159,-95],[-218,-136],[53,-355],[171,39]],[[50785,65066],[40,-176]],[[49822,55759],[-205,-77],[-802,-143],[-105,-57],[-464,542],[-410,86],[-582,518],[178,840],[218,202],[-161,212],[-301,-169]],[[49546,55256],[279,21],[-3,482]],[[49186,54536],[-111,319],[227,308],[244,93]],[[47188,57713],[28,-112],[-415,-15],[-673,-172],[-270,-370],[-226,-155],[-271,-55],[-368,149],[-580,-121],[-519,80],[36,-279],[-490,-392],[-199,-324],[111,-107],[-330,-131],[-235,9]],[[66682,55459],[-297,147],[-364,-291],[-261,-2],[-455,-537],[-87,-222],[64,-166],[-542,-85],[91,-256],[-542,-191],[108,-242]],[[64397,53614],[863,128],[884,-47],[27,-70],[564,-37],[569,96],[-26,320],[-334,297],[11,312],[-101,283],[71,103],[-243,460]],[[65691,61055],[138,179],[127,432],[30,437],[340,176],[233,224],[408,28],[224,-118],[781,129]],[[63186,61898],[245,116],[208,-69],[491,-381],[282,4],[9,330],[258,134],[345,-850],[425,-217],[242,90]],[[61927,65201],[231,-323],[156,64],[101,-466],[236,-234],[-25,-133],[-236,-97],[-197,-227],[-516,-165],[479,-467],[53,-302],[661,-675],[316,-278]],[[62195,65790],[-4,-164],[-264,-425]],[[67367,67124],[-192,-70],[-584,52],[-423,-79],[-225,-133],[-313,308],[-87,213],[-586,-76],[57,-395],[-335,-226],[-411,-40],[-1572,-411],[-59,-548],[-442,71]],[[68828,65208],[-444,520],[-99,-71],[-254,382],[-94,776],[-415,40],[-155,269]],[[68928,64108],[105,340],[-196,203],[-114,-26],[105,583]],[[67972,62542],[806,594],[-174,167],[561,113],[55,331],[-292,361]],[[59965,67759],[18,-55],[-601,-336],[-157,-159]],[[62195,65790],[-120,207],[-189,669],[28,149],[-197,327],[167,223],[-223,264],[-331,-178],[-136,175],[-507,61],[-209,199],[-513,-127]],[[58337,64196],[28,-255],[521,109],[667,58],[802,145],[213,90],[1359,858]],[[63512,69417],[-326,-174],[48,-64],[-412,-171],[13,-67],[-438,-193],[-311,370],[-1195,-499],[-3,-202],[-632,-312],[-352,-92],[61,-254]],[[67367,67124],[-18,477],[-308,520],[-335,179],[-483,86],[-640,51],[-518,246],[-515,472],[-376,128],[-331,1],[-331,133]],[[60032,58304],[392,-440],[273,-697],[106,-106],[400,187],[581,139],[298,198],[-3,414],[240,286],[373,4],[181,116],[434,-178],[197,156],[193,-86],[66,-301],[281,-54],[432,168],[374,-33],[328,-229],[602,-180]],[[60743,61182],[372,-259],[56,-250],[-888,-379],[-25,-237],[-616,-470],[-213,-492],[348,-335],[515,-218],[-4,-216],[-256,-22]],[[63186,61898],[29,-217],[-99,-441],[-155,-193],[-372,-186],[-307,27],[-824,524],[-535,18],[-180,-248]],[[68016,57310],[423,547],[102,336],[161,208],[-789,209],[-108,273],[-331,238],[-327,87],[282,441],[327,179],[-136,121],[-484,31],[-167,-77],[-326,355],[-215,491],[-368,-197],[-369,503]],[[65780,57668],[333,188],[88,-147],[325,85],[345,-5],[411,-233],[20,-232],[243,387],[218,-280],[253,-121]],[[57306,61367],[-142,407],[-372,9],[-163,377],[161,152]],[[54700,59073],[300,651],[292,262],[821,310],[141,401],[720,70],[203,96],[139,226],[-10,278]],[[51300,59820],[111,-153],[254,65],[539,9],[120,-231],[104,120],[452,122],[137,-170],[574,372],[1109,-881]],[[49822,55759],[296,604],[335,237],[204,401],[542,124],[735,67],[430,361],[345,114],[-212,203],[200,75],[501,-235],[319,326],[457,121],[311,464],[283,117],[132,335]],[[49574,59607],[1,-193],[-578,-26],[-117,-92],[191,-363],[-447,-216],[-347,-47],[52,-348],[-388,-34],[-66,174],[-453,-289],[133,-149],[-396,-194],[29,-117]],[[71717,59950],[-129,353],[-316,213],[-414,102],[95,76],[-466,110],[-24,323],[429,135],[-145,219],[76,303],[140,-9],[63,272],[-202,72],[-95,-120],[-573,-29],[-125,-223],[-834,-1],[-921,-73],[-112,616],[-192,253]],[[69339,57336],[119,11],[85,446],[-42,576],[614,663],[553,-136],[439,144],[203,311],[445,418],[-38,181]],[[68016,57310],[230,-83],[542,218],[463,-169],[88,60]],[[63736,53186],[340,-234],[-278,-696],[503,-227],[136,-195],[938,-210],[428,-328],[230,-260],[19,-202],[212,-325],[280,-60],[631,-268],[438,-390],[285,-699],[-85,-497],[257,-263],[168,-62],[72,-291],[615,-290],[164,-265],[262,-175],[379,-495],[805,-612]],[[64397,53614],[-429,-133],[-232,-295]],[[66575,56076],[158,-404],[-51,-213]],[[70187,55813],[-125,-12],[-187,274],[-420,294],[-443,153],[-678,-56],[-74,-141],[-285,75],[-304,-20],[-87,-103],[-491,143],[-100,-127],[-418,-217]],[[70826,55411],[-236,-39],[-342,225],[-61,216]],[[74410,49048],[-175,508],[-27,258],[-269,534],[197,353],[-73,409],[230,33],[-89,600],[228,242],[132,285],[290,53],[58,174],[-116,207],[-329,165],[-414,-179],[-439,-31],[-415,93],[-191,146],[22,455],[-270,273],[-341,179],[-157,191],[-360,211],[-3,112],[-501,441],[-228,99],[6,235],[-270,152],[-80,165]],[[70583,46208],[569,490],[28,165],[1457,711],[175,-33],[-164,331],[241,192],[109,335],[338,-53],[663,386],[165,263],[246,53]],[[57876,52659],[334,-242],[164,-253],[-128,-164],[-706,-283],[170,-280],[300,-24],[287,-119],[75,-255],[-144,-131],[-438,-93],[-194,-244],[133,-305],[432,-46],[91,-168],[-50,-396]],[[63736,53186],[-317,-180],[-793,45],[-15,100],[-699,-13],[-238,-137],[-565,-93],[-324,-277],[-158,84],[-662,-147],[-523,58],[-333,-53],[-562,79],[-671,7]],[[57306,61367],[392,29],[396,-210],[-26,-339],[422,-142],[162,182],[202,-160],[514,240],[305,-32],[361,56],[420,-37],[211,56],[78,172]],[[70187,55813],[71,235],[-65,195],[178,84],[-117,246],[-195,109],[-212,381],[-181,-22],[-327,295]],[[65780,57668],[33,-308],[376,-195],[-60,-212],[446,-877]],[[49546,55256],[121,-329],[297,-277],[414,-240],[271,-257],[506,-238],[129,-244],[377,365],[451,83],[91,-95],[336,82],[482,-7],[-52,152],[900,-294],[55,390],[535,36],[174,68],[-35,296],[900,138],[248,462]],[[55746,55347],[-333,57],[-15,502],[362,307],[439,131],[205,-18],[334,-300],[480,-206],[290,-4],[295,173],[714,151],[178,181],[-202,257],[-558,89],[-244,367],[175,358],[347,62],[180,-81],[322,-365],[412,-19],[135,338],[-9,255],[-222,626],[63,157],[355,72],[583,-133]],[[46030,61082],[-340,-76],[44,-197],[-368,-85],[215,-233],[301,40],[-10,-158],[-461,20],[-534,-91],[-372,-251],[-572,-111],[-210,157],[-314,0],[-501,-157],[-504,-266],[-14,-168],[-327,-198],[-362,-546],[-416,52],[-333,-120],[-127,55],[-429,-706],[-229,-114],[-333,12],[-705,-210],[-71,70],[-413,-496],[-473,-288],[-543,-139],[-129,-310],[-356,-190]],[[63155,71995],[-185,-48],[-438,-358],[56,-202],[-483,-472],[-568,-118],[-311,-300],[16,-99],[-483,-258],[147,186],[-516,248],[-215,219],[-162,-11],[-150,205],[290,166],[-146,168],[-125,-77],[-138,305],[-151,-68],[-7,310],[-639,425],[-89,-225],[-437,292],[-46,-50],[-437,186]],[[63512,69417],[-234,314],[-133,316],[-72,792],[82,1156]],[[57938,72419],[-307,-84],[-961,-421],[-124,-243],[-876,-303]],[[57876,52659],[-65,134],[128,333],[-114,115],[-211,-58],[-403,-430],[-359,48],[-8,146],[199,246],[724,398],[147,202],[-5,394],[237,36],[132,258],[-180,183],[-635,243],[-427,284],[-289,118],[-390,57],[-611,-19]],[[50825,64890],[-231,-37],[-64,215],[-533,-82],[-649,53],[-138,-199],[-290,54],[-258,198],[-56,-69],[143,-336],[-270,-85],[-99,313],[-357,-77],[-551,-206],[-367,237],[-783,-127],[-315,464],[-87,350],[-408,-114],[-125,160],[162,292],[-198,190],[-422,-28],[-350,148]],[[52067,71111],[-351,-67],[-140,221],[-29,272],[-807,519],[-813,140],[-137,277],[-400,140],[-276,-84]],[[54761,81928],[222,-85],[186,-202],[165,63],[441,-460],[936,227],[74,-178],[-393,-271],[-506,-162],[68,-119],[-653,-340],[-272,-345],[-303,-240]],[[54635,82611],[324,-31],[203,-306],[-410,-229],[9,-117]],[[56102,83255],[-251,-140],[-355,-34],[-162,-265],[-699,-205]],[[58526,84030],[-402,-25],[-146,132],[-433,648],[-370,-419],[-307,-487],[-272,-326],[-494,-298]],[[59118,81663],[37,133],[-196,337],[231,98],[-328,411],[-73,-33],[-356,279],[-156,229],[249,913]],[[54917,79507],[321,63],[630,295],[387,371],[313,177],[244,48],[440,381],[438,176],[32,-125],[417,-123],[213,31],[16,487],[190,197],[560,178]],[[54726,79816],[-55,-77],[246,-232]],[[58615,78444],[392,-54],[-766,-121],[-167,112],[-408,-11],[-99,99],[-437,29],[-150,83],[-127,-149],[-822,-317],[-746,386],[143,273],[109,-123],[97,200],[-475,217],[-242,439]],[[60015,78694],[-442,230],[-254,51],[-31,-234],[-673,-297]],[[69917,77970],[-307,422],[-358,-193],[-375,143],[18,-249],[-281,15],[1,126],[-387,-222],[-248,-7],[-305,-480],[-145,99],[-647,-144],[-61,-172],[-272,-177],[-195,220],[-213,-79],[-174,-252],[-305,-216],[243,-662],[36,-251],[149,-140],[-267,-10],[84,-398],[-573,-1],[-181,66],[-416,-231],[-279,147],[-367,9],[45,-665],[-128,-203],[-320,-145],[-608,-60],[-43,192],[-169,-16],[6,385],[182,243],[-203,399],[-222,3],[-237,385],[258,493],[50,389],[-193,9],[-564,-191],[-216,31],[-260,266],[-708,456],[-225,-206],[-186,63],[-121,361],[127,26],[-109,258],[-202,217],[48,476],[-79,195]],[[63155,71995],[2896,744],[1027,1583],[2670,2374],[-206,792],[375,482]],[[50958,75760],[420,-68],[215,154],[168,-88],[273,226],[326,-89],[724,319],[113,190],[533,486],[341,-112],[132,-184],[562,224],[487,-68],[30,-258],[216,72],[117,-130],[1113,-375],[-98,-77],[317,-303],[-234,-170],[464,-15],[694,-1063],[376,135],[158,-231],[-321,-232],[384,-423],[153,-298],[188,-180],[-176,-387],[-695,-396]],[[53570,80577],[-656,11],[-368,-125],[-373,-27],[79,-239],[221,83],[151,-74],[289,130],[112,-108],[-612,-420],[-790,-343],[182,-184],[-583,-273],[19,139],[-661,-146],[83,-233],[-122,-168],[-324,-184],[-50,-730],[424,75],[-31,74],[488,80],[63,-168],[-162,-41],[84,-408],[214,-98],[373,-622],[-331,-477],[-166,0],[-253,-242],[88,-99]],[[54726,79816],[-292,-51],[-170,187],[-628,65],[-171,171],[105,389]],[[62177,82705],[32,-145],[-563,0],[-334,-92],[12,-94],[-475,-146],[-393,-206],[-625,-475],[98,-81],[-136,-192]],[[65723,80939],[42,256],[-660,278],[-298,257],[200,125],[-450,323],[-428,-322],[-78,304],[-206,-157],[-910,664],[-125,-182],[-633,220]],[[60015,78694],[-36,107],[415,329],[266,-111],[362,346],[305,-266],[242,221],[159,-71],[362,73],[445,368],[665,283],[-37,226],[1152,167],[831,310],[5,346],[572,-83]],[[59793,81274],[-96,-67],[66,-254],[249,-507],[554,38],[277,-488],[-304,-230],[-457,111],[-197,-83],[-64,-226],[-283,-395],[-450,-224],[-550,-81],[-347,-133],[73,-215],[351,-76]],[[69925,98313],[1673,-1058],[216,-62],[145,363],[935,-315],[-17,-143],[551,-174],[196,355],[333,-174],[415,453],[494,348],[404,-30],[199,-160]],[[75469,97716],[278,332],[283,216],[-103,384],[-397,-178],[4,200],[-280,318],[-110,274],[-510,643],[-271,-188],[-424,282],[-431,-502],[-803,410],[-693,-809],[-203,-79],[-479,163],[56,-351],[-432,-103],[-1029,-415]],[[51859,85615],[1862,-2040],[401,-499],[513,-465]],[[53651,86629],[-1792,-1014]],[[56102,83255],[-300,167],[-28,563],[-491,809],[-18,140],[-1614,1695]],[[70621,85241],[-129,-285],[-270,-21],[-275,-310],[-802,-328],[-321,-43],[-28,-242],[-209,-204],[171,-38],[112,-213],[549,150],[808,-293],[-1133,-433],[-606,-475],[511,-479],[-562,-363]],[[72656,84995],[-532,69],[-336,-132],[-877,-24],[115,244],[-45,343],[-253,60],[-107,-314]],[[71102,81033],[-882,231],[-318,21],[1231,475],[516,108],[868,447],[149,343],[397,153],[-282,621],[-32,372],[191,246],[-23,297],[-261,648]],[[70719,78259],[126,138],[-447,247],[-158,266],[640,514],[-9,223],[-367,114],[239,354],[-367,70],[234,334],[242,-55],[98,453],[152,116]],[[69917,77970],[802,289]],[[68437,81664],[52,-160],[-441,-92],[69,-362],[-361,2],[-491,86],[-849,-252],[-404,-12],[-289,65]],[[77205,86367],[49,1246],[46,318],[-599,155],[-115,141],[-314,-200],[184,-337],[-511,-232],[-89,133],[-390,-204],[-878,-361],[176,-224],[-96,-127],[-169,133],[-239,-195],[230,-697],[262,-432],[440,237],[651,271],[7,-84],[457,171],[375,311],[523,-23]],[[65672,96605],[1519,-602],[-342,-116],[475,-471],[428,-283],[-173,-143],[591,-747],[115,-308],[535,-889],[342,-13],[447,-213],[466,243],[927,7],[131,-156],[-145,-459],[160,-14]],[[69925,98313],[-3505,-1399],[-748,-309]],[[71148,92441],[167,-28],[244,137],[228,-115],[1103,55],[157,596],[1058,-106],[70,391],[-87,27],[89,357],[194,-31],[238,134],[-88,140],[889,328],[-142,170],[1030,491],[385,381],[140,251],[305,299],[332,166],[-117,379],[-507,413],[-466,163],[85,117],[-502,304],[-581,135],[97,121]],[[71989,77940],[114,383],[174,228],[531,413],[765,684],[1007,1085]],[[70719,78259],[-10,-173],[250,-43],[206,-203],[303,-82],[521,182]],[[74580,80733],[-797,773],[-341,123],[-391,39],[-600,-115],[-622,86],[-482,-263],[-245,-343]],[[56035,87978],[-1646,-932]],[[54389,87046],[1800,-1890],[584,-511],[807,499],[474,233],[91,140],[-396,660],[-1714,1801]],[[50958,75760],[-513,-292],[-144,21],[-157,-365],[-209,-121],[-297,-411],[-298,-289],[-227,-493],[-325,-351],[-326,-24],[-102,-155]],[[58793,89538],[-945,-534]],[[57848,89004],[1593,-1673],[549,-231],[268,120],[342,319],[617,291],[-81,73],[303,81],[248,234],[1259,707],[203,-77],[275,213],[50,274],[-224,577],[-173,246],[-326,-125],[-24,-114],[-1690,-621],[-2244,240]],[[58526,84030],[411,174],[739,176],[484,196],[246,-17],[-29,-262],[160,140],[1091,210],[191,-532],[28,-601],[-97,-175],[427,-634]],[[54389,87046],[-738,-417]],[[57848,89004],[-1813,-1026]],[[63546,96170],[641,-1298],[-692,34],[-3284,-2063],[348,-218],[-745,-647],[-699,-368],[76,-209],[-70,-466],[-328,-1397]],[[64634,96410],[-280,-10],[-440,-164],[-368,-66]],[[73083,89826],[-372,-88],[-21,115],[-1411,-182],[-57,109],[-393,-87],[8,-229],[-343,-305],[-421,-2],[87,604],[-560,-172],[-121,412],[-361,-152],[-132,138],[-474,-123],[-399,194],[-464,-94],[-283,78],[-47,344],[445,91],[-186,320],[-88,-5],[-288,355],[529,471],[-229,342],[-260,-123],[-307,365],[235,74],[-382,467],[-312,44],[99,188],[-449,78],[268,359],[-365,131],[-1395,2867]],[[72471,87975],[77,111],[-123,254],[345,-56],[-46,157],[364,167],[263,-35],[107,181],[-87,250],[79,613],[-367,209]],[[69685,86627],[-12,333],[117,286],[575,247],[-32,64],[-475,-107],[99,313],[262,91],[379,-157],[318,49],[553,290],[218,-51],[784,-10]],[[68437,81664],[-68,5],[-589,909],[851,297],[-183,321],[-540,126],[-401,-57],[-437,30],[-678,-137],[-269,579],[369,298],[424,105],[-158,444],[1106,230],[-187,675],[183,76],[256,-107],[313,76],[37,204],[-321,164],[825,271],[6,87],[420,73],[289,294]],[[59793,81274],[-524,64],[-151,325]],[[54761,81928],[-726,-332],[405,-388],[-318,-132],[117,-117],[-74,-212],[-595,-170]],[[65672,96605],[-638,-239],[-400,44]],[[73083,89826],[153,600],[22,342],[291,221],[49,161],[-395,195],[-62,302],[-280,89],[-712,-55],[-272,-76],[-368,277],[-476,124],[-50,123],[165,312]],[[69685,86627],[203,-132],[-79,-262],[135,-558],[-72,-125],[702,-236],[47,-73]],[[72656,84995],[263,78],[16,497],[654,79],[-58,214],[98,245],[210,102],[-150,490],[-200,-33],[-176,404],[-160,-1],[-315,428],[-316,293],[-191,-13],[140,197]],[[63546,96170],[-5281,-948],[-3206,-569],[-371,92],[-605,-60],[-4417,119],[-953,126],[-1796,407],[27,-57],[1386,-309],[490,-135],[595,-385],[636,-288],[431,-377],[-441,-416],[163,-347],[-532,-237],[269,-410],[-328,-164],[245,-357],[-269,-98],[192,-228],[148,-433],[-474,-90],[52,-130],[268,-121],[275,-741],[143,-999],[-16,-303],[-372,-530],[-166,-113],[316,-368],[1904,-2086]],[[82897,58040],[-333,75]],[[86167,57209],[-122,160],[-254,-158],[-273,296],[-547,-157],[-47,97],[-674,-92],[-300,126],[75,129],[-211,336],[-917,94]],[[81793,55086],[63,-219],[426,-245],[1247,-388],[81,38],[304,-236],[198,169],[455,-106],[277,190],[343,457],[-221,150],[-79,449],[-139,279],[71,349],[420,82],[107,193],[435,163],[-44,288],[97,395],[333,115]],[[82564,58115],[-193,-301],[-170,-101],[159,-251],[115,-568],[-75,-301],[-131,26],[22,-309],[138,-94],[-164,-183],[75,-136],[-447,-445],[-100,-366]],[[76825,68644],[-377,181],[-6,146],[-268,336],[-112,-49],[-98,238],[-269,-13],[-70,329],[-280,24],[73,369],[169,193],[-197,275],[156,69],[-415,133],[36,149],[857,354],[-234,273],[-77,456],[-177,12],[-95,265],[170,33],[456,448],[-331,640],[218,223],[-29,144],[-373,119],[-268,286],[-136,-57],[-23,797],[-89,38],[-203,578],[21,129],[350,192],[240,-11]],[[68828,65208],[331,45],[-33,81],[458,24],[-30,155],[299,-19],[708,471],[240,58],[-27,198],[394,122],[284,16],[1722,1358],[427,101],[442,10],[535,114],[508,0],[334,106],[427,-438],[174,-46],[415,182],[132,405],[-101,155],[358,338]],[[75444,75943],[-308,175],[-223,-121],[-157,167],[-220,-10],[-635,233],[41,151],[-533,-231],[-320,73],[-250,265],[160,129],[-139,136],[139,97],[-672,680],[-338,253]],[[77844,52497],[-63,179],[252,254],[813,194],[86,290],[-38,239],[360,308],[19,217],[-252,105],[45,312],[266,79],[426,271]],[[72042,55979],[212,-277],[747,-275],[1325,68],[845,-222],[540,-360],[220,-344],[894,-710],[300,-466],[-6,-485],[118,-298],[607,-113]],[[75096,58109],[-323,59],[-314,-431],[-310,-112],[-114,258],[-397,95],[-271,158],[-219,252],[-677,-181],[-59,-386],[-350,-401],[97,-230],[-86,-205],[133,-269],[-580,-158],[416,-579]],[[79758,54945],[-540,183],[-134,-13],[-474,216],[-431,-166],[-273,53],[-355,260],[-304,130],[-159,332],[-263,-46],[-537,69],[21,370],[-454,375],[-132,473],[-415,-24],[-15,340],[-181,54],[-16,558]],[[84510,79341],[-255,37],[-947,435],[-1095,247],[-642,531],[-286,182],[-351,90],[-1304,163],[-857,231],[-188,-432],[-1066,34],[-215,210],[-457,178],[-176,371],[-276,-17],[-33,161],[221,128],[-880,-132],[-410,-238],[-713,-787]],[[79652,75288],[418,119],[-152,288],[-143,28],[1,218],[235,5],[10,310],[859,271],[85,180],[-78,287],[214,160],[53,189],[-330,176],[-90,258],[192,400],[-39,187],[318,30],[23,274],[345,14],[72,148],[563,-66],[381,268],[-33,156],[637,217],[416,-120],[944,-62],[-43,118]],[[75444,75943],[472,-10],[76,-195],[-67,-476],[700,86],[86,-218],[555,173],[461,-410],[132,69],[297,-201],[191,52],[541,-10],[135,141],[290,-83],[339,427]],[[87801,72736],[-627,-115],[-328,-112],[-560,-367],[-356,738],[-159,148],[-245,-50]],[[90558,68001],[69,278],[821,205],[740,312],[161,367],[-30,182],[-265,201],[64,171],[-467,391],[-399,251],[-138,326],[-673,278],[-186,174],[-739,218],[-872,500],[32,183],[-253,337],[-375,161],[-247,200]],[[85526,72978],[-73,-189],[-541,-559],[-376,-83],[-296,-180],[-213,6],[-315,-427],[-41,-278],[162,-526],[335,-31],[374,-261],[-55,-114],[556,-338],[-21,-273],[-263,-199],[393,-523],[437,-168],[146,-206],[228,-46],[445,-385],[255,-148],[-96,-301],[110,-393],[-252,-155],[-18,-128],[382,-279],[641,107],[53,-127],[244,177],[312,93],[397,9],[-158,345],[757,99],[295,261],[373,85],[374,197],[481,-39]],[[86790,57502],[-623,-293]],[[89462,34823],[515,77],[626,-48],[692,162],[753,723],[-331,830],[-533,697],[-477,724],[332,126],[420,-99],[225,41],[378,-70],[200,121],[480,-107],[986,162],[265,-83],[555,32],[93,-169],[319,-271],[397,-213],[-64,-454],[70,-192],[287,-191],[314,-39],[193,-228],[-76,-570],[150,-361],[154,-139],[104,285],[74,523],[204,106],[386,416],[-12,187],[627,185],[1703,1209],[58,75],[-1255,-119],[40,322],[241,284],[-31,314],[163,325],[-109,176],[207,683],[-215,326],[383,533],[452,458],[-201,449],[-310,271],[4,268],[713,512],[-302,501],[16,241],[493,399],[181,26],[-513,445],[-461,-99],[-848,83],[-249,266],[-339,149],[-359,742],[-401,-216],[-1202,76],[-1040,99],[-22,245],[102,330],[444,473],[47,361],[196,281],[-172,644],[-334,121],[-1265,278],[-379,-28],[-476,40],[-892,370],[-312,-17],[-803,84],[-651,124],[-716,-21],[-387,93],[-315,-161],[-536,425],[-271,137],[-646,645],[-250,507],[-81,563],[55,659],[1,574],[119,299],[386,578],[494,598],[160,402],[25,361],[-181,661],[-7,452],[70,533],[-290,287],[-58,267],[-235,250],[-263,62],[98,181],[-452,60]],[[79763,54952],[330,-488],[142,-401],[123,-79],[53,-382],[-119,-87],[135,-290],[610,-230],[345,-352],[358,-68],[6,-372],[-324,-73],[-427,27],[103,-591],[287,-343],[180,-58],[-51,-435],[-191,-183],[-10,-363],[96,-324],[771,-551],[172,-401],[-34,-419],[251,-115],[356,-872],[-126,-183],[348,-326],[-452,-414],[80,-489],[-793,-399],[67,-315],[-10,-833],[-228,-778],[-792,-963],[-104,-350],[74,-282],[-306,-566],[-332,-343],[-175,-300]],[[81793,55086],[-278,-146],[-335,-35],[-341,62],[-1046,30],[-30,-45]],[[79763,54952],[-5,-7]],[[77844,52497],[256,-210],[-78,-463],[72,-79],[-139,-438],[-274,-230],[35,-198],[-111,-182],[-263,-60],[-412,-394],[-430,-266],[-94,-321],[4,-315],[-851,-62],[-1149,-231]],[[75328,58508],[10,-368],[-242,-31]],[[82564,58115],[-139,41],[-94,-177],[-230,98],[101,192],[-262,-103],[-437,131],[-886,427],[-312,87],[-146,195],[-229,10],[-162,-116],[-286,48],[19,-124],[-585,-53],[-462,442],[-465,33],[-400,-36],[-203,-210],[-234,-98],[-243,335],[-175,60],[5,-327],[-555,287],[-24,-60],[-537,-149],[-97,-339],[-198,-201]],[[72042,55979],[-482,-252],[-734,-316]],[[71717,59950],[231,16],[415,-147],[159,-273],[203,-156],[279,-2],[902,-333],[403,75],[479,-294],[355,-338],[185,10]],[[82897,58040],[154,137],[103,349],[269,561],[-350,363],[-38,249],[256,325],[-89,204],[-379,232],[-90,170],[-254,-38],[-68,169],[-398,22],[-120,444],[98,125],[-261,170],[21,113],[-222,328],[-227,132],[-287,14],[-444,155],[-292,-80],[-466,15],[-58,-128],[-442,72],[-786,-234],[47,-82],[-450,66],[-19,-66],[-422,68],[-852,-145],[-797,110],[-67,268],[-283,75],[-11,244],[-265,80],[45,129],[-390,139],[-153,132],[58,137],[-175,242],[-197,564],[-367,409],[-448,30],[-489,312],[-186,-39],[-291,187],[-689,194],[-191,-159],[-155,126],[-85,-132],[-825,-168],[-621,-230],[-232,-10],[-369,-366],[-268,-40],[-452,124]],[[84792,73252],[-570,-47],[-73,271],[-312,74],[-43,172],[-729,266],[5,388],[-313,113],[-513,-183],[-358,93],[-533,469],[-329,-243],[-272,20],[-146,292],[88,113],[-659,4],[31,89],[-349,-9],[-65,154]],[[76825,68644],[89,381],[187,132],[540,3],[-27,-145],[255,-3],[3,-280],[211,-72],[-26,-205],[398,11],[177,-173],[711,71],[342,128],[305,29],[401,178],[359,395],[631,247],[339,446],[-131,212],[159,337],[-38,141],[135,375],[438,519],[-2,88],[439,293],[438,100],[81,105],[-301,441],[302,100],[590,-46],[92,108],[-87,244],[228,166],[577,30],[222,132],[-70,120]],[[85526,72978],[100,91],[-9,309]],[[86790,57502],[-428,492],[-18,546],[-407,121],[128,227],[633,357],[170,336],[694,311],[-44,278],[95,125],[525,326],[-1,166],[-340,267],[-35,127],[227,438],[-234,338],[-65,358],[508,472],[417,571],[75,489],[196,242],[-29,339],[207,560],[232,256],[291,155],[173,280],[425,328],[431,173],[40,153],[-232,238],[272,552],[39,297],[-177,581]],[[85617,73378],[-825,-126]],[[95213,79236],[-670,-122],[-499,31],[-1148,-163],[-250,27],[-293,-155],[-231,112],[-814,43],[-241,-90],[-540,36],[-31,88],[-621,15],[-89,-105],[-261,73],[-135,-249],[-322,-139],[-138,-294],[-481,-175],[-456,-93],[-266,-203],[-171,-370],[-18,-214],[-282,-189],[168,-474],[371,-222],[-286,-261],[-437,-228],[-477,-106],[-203,-193],[333,69],[42,-308],[315,-52],[20,-258],[-309,-311],[-366,-84],[229,-105],[-416,-196],[135,-251],[-44,-167],[-714,-575]],[[87801,72736],[298,89],[378,211],[134,-7],[335,223],[410,104],[-2,546],[204,93],[-120,268],[306,36],[12,172],[282,120],[215,-58],[-62,-293],[546,165],[405,-104],[656,-245],[-58,-58],[534,-283],[-457,-297],[-317,153],[-432,-359],[474,-552],[691,-95],[436,78],[157,151],[185,-231],[196,-10],[-8,-181],[249,-97],[279,219],[819,296],[321,240],[325,-78],[366,301],[434,656],[514,334],[240,431],[-203,356],[70,646],[-303,314],[-405,126],[-229,866],[107,821],[70,956],[-74,155],[-566,322]],[[95213,79236],[-382,121],[-1060,196],[-1979,474],[-569,24],[-1811,-326],[-468,-41],[-448,32],[-904,153],[-847,228],[-926,-14],[-468,-188],[-438,-394],[-403,-160]],[[19115,18144],[-398,-412],[-111,-557],[-203,39],[-86,-684],[-149,-101]],[[21393,13221],[-926,684],[-222,273],[-158,338],[71,356],[-87,218],[166,153],[-70,653],[70,253],[-25,758],[157,682],[-81,89],[-304,-121],[-610,-3],[-177,-78],[-269,165],[51,179],[292,134],[-156,190]],[[13303,13248],[283,-892],[28,-346],[410,-552],[437,-501],[535,-429],[264,-132],[411,58],[525,-583],[1321,-64],[864,135],[321,819],[255,400],[497,256],[469,357],[300,359],[590,538],[252,145],[328,405]],[[14942,14349],[-69,-44],[57,-413],[-166,8],[-960,-475],[2,-108],[-503,-69]],[[18168,16429],[-30,-215],[-270,-300],[-121,-256],[-251,-276],[42,-207],[427,55],[-39,-342],[374,-89],[-37,-350],[-185,-112],[-444,-15],[-263,-172],[-280,8],[-623,-145],[-423,332],[-137,-139],[-266,28],[-198,279],[-302,23],[-200,-187]],[[13652,17643],[375,-470],[126,40],[497,-256],[-181,-404],[-43,-360],[-285,-431],[-36,-1021],[449,-112],[322,-10],[66,-270]],[[18168,16429],[-341,52],[62,317],[-113,103],[240,476],[-526,139],[25,253],[-254,299],[-22,256],[-361,18],[-79,-123],[-212,52],[-1014,-373],[-594,-133],[-288,38],[-415,-113],[-604,16],[-20,-63]],[[21646,13377],[507,254],[1399,758],[222,205],[161,-71],[-88,-150],[-13,-572],[76,-176],[-261,-362],[-160,-643],[110,-260],[180,197],[458,265],[267,340],[-64,156],[498,-7],[189,-115],[163,50],[577,-89],[210,157],[190,-101],[24,-181],[440,-246],[179,50],[187,-158],[623,-268],[521,-84],[377,-534],[304,33],[384,-299],[158,17],[102,-284],[406,-116],[684,39],[214,143],[250,-151],[689,10],[450,227],[136,-99],[414,-27],[-4,-119],[236,-123],[70,-184],[576,-244],[567,-333],[123,-287],[215,-258],[736,-360],[212,66],[288,-383],[-152,-85],[93,-273],[-113,-316],[236,-493],[-31,-226],[323,-535],[612,-436],[253,-98]],[[23318,21421],[269,-261],[-97,-66],[382,-213],[-219,-220],[160,-100],[-38,-296],[-263,-254],[-23,-201],[-338,-561],[116,-501],[-13,-423],[-384,-732],[-52,-855],[-111,-481],[123,-485],[-221,-516],[-191,-7],[-167,-313],[-167,-499],[-403,-598],[-35,-462]],[[24680,21754],[-455,-259],[-228,-6],[-113,168],[-408,-258],[-158,22]],[[40224,16913],[-221,-46],[-518,41],[-130,398],[-255,147],[-212,534],[-452,327],[44,321],[-208,590],[-349,138],[-514,102],[-983,-162],[-1112,-236],[-717,-199],[-622,115],[-614,354],[-453,-6],[-407,211],[-230,7],[-547,312],[-582,386],[-297,146],[-80,152],[-479,211],[-637,121],[-46,202],[-340,199],[-351,46],[-721,-56],[-288,-215],[-633,-76],[-93,126],[-504,223],[-539,169],[163,369],[-176,61],[48,180],[-157,89],[-337,-128],[-83,139],[-322,106],[-590,-557]],[[13652,17643],[-1116,106],[-65,240],[488,619],[-248,123],[-229,-350],[-250,-181],[-794,-728],[95,-128],[-162,-120],[74,-123],[-202,-513],[-683,-761],[-1,-153],[-301,-179],[331,-249],[365,-412],[427,-863],[708,-426],[259,-359],[569,-5],[386,67]],[[21393,13221],[253,156]],[[23318,21421],[-309,-165],[71,-109],[-376,13],[-105,110],[-298,-223],[-337,-413],[-864,-707],[-213,-368],[-400,-176],[-226,-339],[-201,25],[-83,-163],[-492,-260],[-29,-150],[-341,-352]],[[22713,28702],[-827,-519],[9,-322],[254,180],[394,-356],[-150,-93],[-585,38],[83,223],[-126,67],[182,214],[-270,105],[-219,-242],[-205,194],[-401,-383],[-397,190],[-196,-96],[-492,-494],[-610,-295],[-378,4],[-584,-497],[-227,-130],[-585,-521],[36,-80],[-487,-429]],[[24979,23875],[-116,97],[-551,86],[-268,225],[-6,174],[210,213],[-448,633],[188,130],[251,324],[228,102],[294,273],[328,16],[287,225],[73,209],[546,271],[-496,558],[-280,-11],[-238,392],[-750,236],[-455,44],[181,131],[92,246],[163,122],[-218,280],[61,105],[-809,-293],[-533,39]],[[24054,23417],[321,370],[387,-37],[217,125]],[[16932,25460],[764,-335],[389,-43],[440,-300],[433,-165],[-76,-180],[444,-191],[367,-539],[649,-1259],[787,376],[790,-916],[293,153],[89,283],[-71,103],[275,469],[360,-40],[778,292],[411,249]],[[24054,23417],[577,-155],[-212,-209],[25,-150],[-206,-170],[140,-176],[-188,-105],[118,-287],[409,-371],[-37,-40]],[[32616,28793],[-631,-497],[-285,-363],[-622,-405],[-409,-323],[-832,-801],[-246,-187],[-325,174],[-261,-334],[-922,489],[-103,-48],[-953,-1398],[-207,-452],[-773,-546],[-22,-114],[-556,-101],[-224,-100],[-266,88]],[[15295,25502],[511,116],[158,194],[294,-90],[150,-257],[336,-163],[188,158]],[[22713,28702],[140,211],[253,150],[-200,137],[224,169],[26,246],[746,755],[232,12],[208,214],[-96,179],[296,20],[518,222],[355,-18],[165,261]]],"transform":{"scale":[0.003700244566736064,-0.004800048000480005],"translate":[294.98962178548015,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/ge.json b/src/onegov/election_day/static/mapdata/2025/ge.json new file mode 100644 index 0000000000..a8107aece1 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/ge.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":6601,"properties":{"id":6601,"name":"Aire-la-Ville"},"arcs":[[-1,-2,-3,-4]]},{"type":"Polygon","id":6602,"properties":{"id":6602,"name":"Anières"},"arcs":[[-5,-6,-7,-8,-9]]},{"type":"Polygon","id":6603,"properties":{"id":6603,"name":"Avully"},"arcs":[[-10,-11,-12,-13,-14,-15,-16]]},{"type":"Polygon","id":6604,"properties":{"id":6604,"name":"Avusy"},"arcs":[[-17,-18,11,-19,-20]]},{"type":"Polygon","id":6605,"properties":{"id":6605,"name":"Bardonnex"},"arcs":[[-21,-22,-23,-24]]},{"type":"Polygon","id":6606,"properties":{"id":6606,"name":"Bellevue"},"arcs":[[-25,-26,-27,-28,-29,-30,-31]]},{"type":"Polygon","id":6607,"properties":{"id":6607,"name":"Bernex"},"arcs":[[-32,-33,-34,-35,-36,-37,-38,-39,0]]},{"type":"Polygon","id":6608,"properties":{"id":6608,"name":"Carouge (GE)"},"arcs":[[-40,-41,-42]]},{"type":"Polygon","id":6609,"properties":{"id":6609,"name":"Cartigny"},"arcs":[[-43,1,38,-44,9]]},{"type":"MultiPolygon","id":6610,"properties":{"id":6610,"name":"Céligny"},"arcs":[[[-45]],[[-46]]]},{"type":"Polygon","id":6611,"properties":{"id":6611,"name":"Chancy"},"arcs":[[-47,12,17]]},{"type":"Polygon","id":6612,"properties":{"id":6612,"name":"Chêne-Bougeries"},"arcs":[[-48,-49,-50,-51,-52,-53]]},{"type":"Polygon","id":6613,"properties":{"id":6613,"name":"Chêne-Bourg"},"arcs":[[-54,48,-55]]},{"type":"Polygon","id":6614,"properties":{"id":6614,"name":"Choulex"},"arcs":[[-56,-57,-58,-59,-60,-61,-62]]},{"type":"Polygon","id":6615,"properties":{"id":6615,"name":"Collex-Bossy"},"arcs":[[-63,-64,27]]},{"type":"Polygon","id":6616,"properties":{"id":6616,"name":"Collonge-Bellerive"},"arcs":[[30,-65,-66,-67,-68,58,-69,-70]]},{"type":"Polygon","id":6617,"properties":{"id":6617,"name":"Cologny"},"arcs":[[-71,68,57,-72,52,-73]]},{"type":"Polygon","id":6618,"properties":{"id":6618,"name":"Confignon"},"arcs":[[-74,-75,34,-76]]},{"type":"Polygon","id":6619,"properties":{"id":6619,"name":"Corsier (GE)"},"arcs":[[-77,66,-78,7,-79,-80]]},{"type":"Polygon","id":6620,"properties":{"id":6620,"name":"Dardagny"},"arcs":[[-81,-82,14,-83]]},{"type":"Polygon","id":6621,"properties":{"id":6621,"name":"Genève"},"arcs":[[-84,-85,72,51,-86,40,-87,-88]]},{"type":"Polygon","id":6622,"properties":{"id":6622,"name":"Genthod"},"arcs":[[29,-89,64]]},{"type":"Polygon","id":6623,"properties":{"id":6623,"name":"Le Grand-Saconnex"},"arcs":[[-90,25,-91,83,-92,-93]]},{"type":"Polygon","id":6624,"properties":{"id":6624,"name":"Gy"},"arcs":[[-94,-95,79,-96]]},{"type":"Polygon","id":6625,"properties":{"id":6625,"name":"Hermance"},"arcs":[[5,-97]]},{"type":"Polygon","id":6626,"properties":{"id":6626,"name":"Jussy"},"arcs":[[-98,-99,-100,93]]},{"type":"Polygon","id":6627,"properties":{"id":6627,"name":"Laconnex"},"arcs":[[43,37,-101,18,10]]},{"type":"Polygon","id":6628,"properties":{"id":6628,"name":"Lancy"},"arcs":[[86,39,-102,-103,-104]]},{"type":"Polygon","id":6629,"properties":{"id":6629,"name":"Meinier"},"arcs":[[59,67,76,94,99,-105]]},{"type":"Polygon","id":6630,"properties":{"id":6630,"name":"Meyrin"},"arcs":[[92,-106,-107,-108]]},{"type":"Polygon","id":6631,"properties":{"id":6631,"name":"Onex"},"arcs":[[75,33,-109,102,-110]]},{"type":"Polygon","id":6632,"properties":{"id":6632,"name":"Perly-Certoux"},"arcs":[[23,-111,-112,35,74,-113]]},{"type":"Polygon","id":6633,"properties":{"id":6633,"name":"Plan-les-Ouates"},"arcs":[[112,73,109,101,-114,-115,20]]},{"type":"Polygon","id":6634,"properties":{"id":6634,"name":"Pregny-Chambésy"},"arcs":[[69,70,84,90,24]]},{"type":"Polygon","id":6635,"properties":{"id":6635,"name":"Presinge"},"arcs":[[104,98,-116,-117,60]]},{"type":"Polygon","id":6636,"properties":{"id":6636,"name":"Puplinge"},"arcs":[[61,116,-118,-119]]},{"type":"Polygon","id":6637,"properties":{"id":6637,"name":"Russin"},"arcs":[[15,81,-120,2,42]]},{"type":"Polygon","id":6638,"properties":{"id":6638,"name":"Satigny"},"arcs":[[-121,106,-122,31,3,119,80]]},{"type":"Polygon","id":6639,"properties":{"id":6639,"name":"Soral"},"arcs":[[-123,19,100,36,111]]},{"type":"Polygon","id":6640,"properties":{"id":6640,"name":"Thônex"},"arcs":[[55,118,-124,-125,49,53,-126]]},{"type":"Polygon","id":6641,"properties":{"id":6641,"name":"Troinex"},"arcs":[[-127,21,114,-128]]},{"type":"Polygon","id":6642,"properties":{"id":6642,"name":"Vandoeuvres"},"arcs":[[56,125,54,47,71]]},{"type":"Polygon","id":6643,"properties":{"id":6643,"name":"Vernier"},"arcs":[[103,108,32,121,105,91,87]]},{"type":"Polygon","id":6644,"properties":{"id":6644,"name":"Versoix"},"arcs":[[8,77,65,88,28,63,-129]]},{"type":"Polygon","id":6645,"properties":{"id":6645,"name":"Veyrier"},"arcs":[[127,113,41,85,50,124,-130]]}]}},"arcs":[[[26897,22469],[69,232],[194,-76],[485,4],[140,-107],[182,186],[503,1034],[-863,499],[670,484],[936,930],[264,373],[232,469],[-139,523]],[[20800,24302],[1421,-787],[1644,-1119],[528,421],[472,488],[379,270],[84,158],[91,-206],[195,87],[363,-53],[110,-76],[190,-507],[331,-310],[238,-59],[51,-140]],[[21657,29797],[-255,-194],[-392,-520],[-231,-465],[-69,-567],[150,-599],[579,-1236],[116,-377],[17,-264],[-108,-507],[-187,-320],[-477,-446]],[[29570,27020],[-517,-80],[-446,82],[-540,242],[-444,120],[-696,-27],[-611,79],[-525,229],[-1037,900],[-468,205],[-874,793],[-588,291],[-553,122],[-345,-48],[-269,-131]],[[72320,71932],[-3270,-6372]],[[81728,65708],[-130,303],[-295,399],[-678,452],[-423,317],[-668,569],[-7214,4184]],[[83168,55984],[-1852,4410],[-269,124],[-324,305],[-229,303],[-174,125],[-268,412],[-65,212],[-2,344],[-119,214],[194,171],[125,380],[-45,148],[139,82],[-135,249],[95,126],[-185,205],[59,391],[-152,56],[51,150],[326,-154],[203,125],[-38,233],[262,220],[369,396],[-84,230],[32,180],[209,4],[266,171],[171,-88]],[[67999,63512],[5918,-3432],[144,-279],[302,-238],[203,-235],[489,-106],[255,-200],[304,-548],[797,-451],[95,-495],[162,-280],[630,552],[1900,-234],[141,-194],[776,-690],[-34,-266],[368,-241],[-32,-170],[254,-125],[970,17],[556,-277],[398,-131],[376,369],[197,126]],[[69050,65560],[-1051,-2048]],[[18337,14727],[-84,36],[-153,365],[-9,237],[91,27],[-161,400],[-67,511],[-142,347],[-16,188],[-371,650],[-419,312],[-170,212],[-387,289],[-210,228],[-156,340],[-24,431],[-100,127],[-81,435],[-169,556]],[[18260,14677],[77,50]],[[14176,12197],[542,350],[796,473],[1830,1126],[846,545],[70,-14]],[[5789,13770],[309,-249],[9,-196],[162,-52],[288,-391],[347,-106],[59,-153],[684,-3],[112,89],[279,-91],[48,-226],[342,135],[433,304],[405,726],[312,281],[305,459],[177,417],[386,493],[462,-45],[267,-182],[183,-267],[424,-264],[1107,87],[351,-503],[392,-241],[-66,-124],[240,-154],[-92,-230],[-194,-252],[537,-634],[119,-201]],[[10376,20505],[-213,-146],[-217,-276],[-327,-954],[-82,-678],[-70,-225],[-228,-347],[-162,-37],[-231,195],[-88,476],[-289,481],[-362,241],[-270,-18],[-212,-176],[-297,-828],[-15,-613],[-188,-1240],[-184,-512],[-892,-1483],[-260,-595]],[[15423,20404],[-856,-439],[-430,-150],[-362,-9],[-398,89],[-778,244],[-505,185],[-1061,260],[-223,27],[-434,-106]],[[15709,20418],[-286,-14]],[[7516,5749],[191,105],[207,259],[461,99],[128,-234],[168,24],[147,-150],[234,294],[192,3],[64,203],[431,-213],[503,252],[246,53],[303,215],[147,-399],[116,167],[456,-167],[109,-343],[296,65],[157,-80],[330,118],[115,-246],[142,23],[142,-207],[354,1],[161,-170],[170,93],[167,-42],[384,171],[287,-96],[270,194],[242,91],[270,-172],[20,-145],[257,61],[178,-62],[422,31],[118,-46],[156,183],[173,-84],[149,287],[314,-119],[362,28],[316,-254],[551,-126],[239,-374],[126,164],[313,14],[284,-441]],[[14176,12197],[-656,-387],[-355,-258],[-599,-325],[-994,-408],[-914,-337],[-494,-89],[-290,-127],[-479,-312],[-446,-107],[-431,-304],[24,-344],[-63,-232],[-347,-461],[-214,-1292],[-168,-200],[-103,-251],[-131,-1014]],[[22458,7777],[-477,513],[-116,219],[-1088,724],[-169,-169],[-850,526],[-750,378],[-574,256],[-952,108],[-251,52],[138,398],[449,1007],[129,225],[229,729],[33,1340],[79,397],[-28,197]],[[19084,4777],[166,213],[266,177],[217,379],[264,164],[601,676],[1322,1006],[538,385]],[[51537,10363],[-338,202],[-309,-113],[-323,96],[-232,167],[-438,-589],[-1275,-411],[-536,177],[-174,-293],[-170,-95],[-497,-443],[-361,142],[-68,-39],[133,427],[-1444,733],[4,-138],[-529,358],[-283,146],[-215,303],[-310,262],[-138,-199],[-1054,789],[-715,364],[-867,-1701],[-90,255],[-398,369],[-11,107],[-260,252],[-411,222]],[[53476,6982],[-221,169],[-110,366],[-93,-6],[-200,267],[-450,397],[-167,-18],[-440,285],[-502,150],[157,519],[79,606],[8,646]],[[38216,9299],[307,-275],[214,-333],[-48,-242],[408,-374],[230,-367],[727,-1921],[220,109],[948,35],[111,46],[915,-135],[34,-179],[358,-311],[475,246],[248,-314],[610,14],[496,93],[681,-125],[733,-97],[236,53],[878,-315],[506,-309],[405,-361],[434,-100],[672,26],[184,99],[257,360],[212,-280],[1008,298],[-13,293],[123,264],[717,645],[381,185],[251,298],[-38,233],[110,198],[35,273],[148,-190],[66,-399],[609,-401],[677,728],[-265,215]],[[40228,11713],[-64,-311],[-180,-376],[-342,-421],[-403,-302],[-499,-604],[-524,-400]],[[49140,49041],[83,161],[445,455],[457,350],[1194,660],[414,156],[796,547],[378,121],[85,-32],[281,-361],[456,-465],[585,-443],[76,-2],[283,-289],[616,-449],[536,-16],[348,-285],[5527,-1674]],[[47808,51446],[328,-222],[131,-573],[202,-476],[189,-301],[269,208],[395,160],[-197,-904],[15,-297]],[[46805,55833],[762,-1155],[-289,-198],[339,-543],[-347,-304],[-205,-499],[101,-253],[151,-162],[359,-205],[113,-180],[278,-59],[-177,-321],[171,-253],[-253,-255]],[[52876,60644],[-6071,-4811]],[[52871,60612],[5,32]],[[62813,51627],[-5805,1758],[-239,116],[-603,413],[-281,258],[-397,289],[-1500,738],[-257,182],[-329,336],[229,528],[-84,691],[1,629],[-74,233],[-457,1095],[-174,286],[484,1146],[-14,62],[-406,160],[-36,65]],[[61700,47475],[1113,4152]],[[33559,31026],[-363,-103],[-340,-220],[-183,-182],[-337,-510],[-178,-358],[-377,-1108],[-185,-400],[-248,-338],[-307,-278],[-341,-201],[-356,-123],[-774,-185]],[[37779,27076],[-380,369],[-148,341],[-58,444],[158,416],[207,205],[434,299],[182,238],[31,218],[-36,631],[31,328],[149,684],[410,1337],[382,752],[64,354],[-40,243],[-247,475],[-297,253],[-443,92],[-472,-191],[-499,-428],[-540,-650],[-261,-398],[-601,-1065],[-161,-244],[-391,-452],[-247,-210],[-397,-147],[-1050,56]],[[37036,26668],[127,18],[616,390]],[[36871,15457],[-314,517],[-702,-381],[-252,111],[-253,346],[36,145],[-105,147],[-166,-97],[-609,730],[-274,-204],[-33,76],[-412,219],[-59,123],[360,293],[97,368],[-254,845],[-75,125],[508,377],[525,468],[-25,174],[-281,385],[161,153],[569,189],[317,51],[1406,69],[501,-24],[27,405],[-67,831],[25,551],[-130,661],[-481,832],[-419,541],[-273,993],[49,277],[217,103],[299,314],[83,386],[169,112]],[[33414,8297],[215,360],[222,902],[145,778],[135,2045],[-53,950],[286,-309],[502,525],[169,-190],[752,857],[-254,328],[1338,914]],[[26445,9319],[864,1680],[162,256],[319,326],[331,227],[1578,930],[970,-977],[903,-811],[1037,-1060],[181,-240],[188,-628],[436,-725]],[[23369,17638],[624,-716],[1002,-1284],[149,-588],[183,-213],[-166,-140],[93,-271],[-94,-301],[206,-260],[-462,-237],[336,-440],[846,-980],[367,-371],[-328,-517],[416,-706],[-301,-395],[205,-900]],[[26897,22469],[114,-174],[-49,-135],[121,-182],[46,-743],[-93,-278],[-201,-253],[-443,-970],[-301,-339],[-316,-233],[-449,-208],[-133,51],[-460,-779],[-814,-220],[-292,-156],[-258,-212]],[[48522,24477],[46,-620],[48,8],[41,-450],[41,-1825],[231,-26],[434,416],[95,16],[25,-668],[-24,-1719],[-216,-351],[-296,-140],[176,-339],[848,807],[385,-588],[152,-563],[197,-17],[346,-240],[-69,-287],[139,-160],[175,-368],[17,-415],[229,-253],[-201,-211],[220,-121],[229,-364],[164,52]],[[55801,20949],[114,1139],[115,943],[-91,413],[-302,338],[-233,79],[-1134,126],[-625,-37],[-573,88],[-321,182],[-223,285],[-135,466],[-489,-180],[-40,49],[-714,36],[-543,882],[-900,-680],[-72,69],[-868,-651],[-245,-19]],[[51954,16051],[57,302],[-44,244],[-295,973],[-93,225],[107,38],[394,426],[100,11],[743,952],[661,703],[487,-422],[149,-39],[173,190],[78,-81],[225,246],[-95,63],[291,141],[194,-51],[245,241],[178,538],[292,198]],[[20800,24302],[-1286,-1124],[-591,-371],[-858,-372],[-386,-254],[-225,-272],[-374,-694],[-262,-345],[-258,-200],[-851,-252]],[[18337,14727],[717,457],[632,373],[1244,695],[1259,603],[411,174],[355,210],[414,399]],[[67860,90997],[1463,-1080],[1424,-1068],[169,358],[552,-139],[-55,-91],[250,-135],[7061,-3720],[2626,5630],[-7973,4200],[-237,282],[-88,-101],[-555,333],[-385,166],[-152,130],[-703,126],[-419,-136],[-412,-62],[-439,363],[-143,11],[-18,233],[-145,386],[-221,332],[-160,348],[190,247],[-184,298],[43,164],[-396,149],[-588,90],[-664,-17],[-917,-151],[-243,2],[-352,121],[-230,287],[-61,198],[-443,439],[-692,491],[-364,318],[-509,-341],[-528,-281],[-26,39],[-581,-331],[-114,-256],[612,-753],[-653,-334],[-795,-347],[246,-976],[174,-493],[97,-149],[695,-375],[1326,-463],[826,-700],[-106,-190],[919,-525],[256,-5],[200,159],[258,86],[198,-257],[577,-414],[495,108],[157,-103],[260,-10],[-523,-2091]],[[65445,91950],[-234,173],[-424,458],[-98,157],[-269,204],[-1415,1400],[-258,-429],[-5,-214],[-202,-370],[-595,394],[-595,-1117],[-850,-1753],[462,-428],[630,-490],[153,-185],[55,174],[259,108],[76,320],[-135,524],[33,532],[449,460],[206,590],[582,-471],[71,-196],[1068,-684],[110,154],[146,-224],[780,913]],[[5789,13770],[-302,-728],[-62,-352],[-407,-937],[-375,-612],[-763,-1055],[-123,-214],[-421,-968],[-217,-727],[-400,-550],[-139,-319],[-194,-641],[-7,-504],[95,-560],[308,-623],[191,-517],[21,-323],[-75,-247],[-306,-510],[-466,-318],[-346,-138],[-959,-514],[-262,-171],[-580,-603],[148,-240],[89,-1308],[149,-91],[401,355],[311,180],[342,327],[7,82],[1025,-282],[114,-220],[64,131],[308,81],[390,384],[374,135],[81,254],[296,-24],[288,55],[293,-107],[98,-122],[337,309],[355,126],[370,201],[226,194],[456,816],[448,385],[364,399],[212,1280],[97,390],[-163,101],[36,319]],[[69234,32438],[-150,1],[-401,492],[-309,-282],[-763,-262]],[[65073,25245],[-10,460],[-141,204],[-194,-9],[-103,336],[194,170],[148,578],[93,102],[330,-233],[684,321],[330,78],[158,197],[-103,441],[72,287],[423,281],[86,380],[111,130],[-96,160],[147,224],[484,124],[-16,276],[147,254],[287,275],[265,-56],[448,156],[-19,249],[509,120],[139,346],[-216,294],[49,330],[-44,153],[127,153],[-128,412]],[[63501,20657],[180,243],[276,52],[37,294],[271,110],[-50,211],[123,190],[-153,272],[-173,173],[-129,553],[201,-13],[-4,277],[100,353],[-106,268],[333,384],[-26,122],[212,334],[292,159],[-10,115],[198,491]],[[59782,24063],[229,-272],[218,-378],[232,-669],[77,-133],[192,-723],[41,-766],[-27,-505],[-109,-282],[-279,-349],[-226,-139],[-78,-158],[29,-308],[202,-214],[219,-80],[296,7],[421,155],[785,443],[343,257],[209,384],[242,260],[397,140],[306,-76]],[[62102,30054],[-431,-634],[113,-172],[-113,-484],[-350,-732],[-547,-882],[387,-269],[-36,-72],[-913,-1052],[-558,-600],[128,-1094]],[[67611,32387],[-1169,-652],[-247,213],[-623,186],[-638,-723],[-302,153],[-819,267],[-514,216],[-158,-54],[-162,-304],[183,-418],[-407,-336],[-653,-881]],[[65073,25245],[209,-81],[395,-18],[684,336],[111,150],[382,-209],[315,-39],[503,-295],[208,482],[420,-230],[45,25],[532,2216],[718,123],[164,525],[-200,39],[277,390],[397,286],[121,30],[-314,472],[350,208],[-243,804],[-196,298],[318,393],[-147,136],[102,183],[61,393],[14,957],[-333,485]],[[69966,33304],[-336,-174],[-201,-248],[-195,-444]],[[73676,33768],[38,8]],[[69561,43437],[491,-647],[103,-82],[226,154],[291,-710],[167,-303],[625,-617],[160,-75],[310,-337],[626,-399],[210,-2],[87,124],[689,-117],[348,-212],[249,-309],[-473,-1271],[252,-627],[403,-603],[244,-277],[-116,-632],[-49,-752],[-220,-480],[-581,-659],[73,-836]],[[69549,43453],[12,-16]],[[72897,45067],[-131,179],[-506,-78],[-973,-583],[-703,-39],[-323,-152],[-712,-941]],[[81127,40395],[-1269,417],[33,90],[-793,264],[61,561],[-67,8],[155,1473],[246,579],[-38,82],[-1642,845],[98,-351],[-546,-545],[-179,-218],[-298,-240],[-83,-152],[-305,208],[-110,-220],[-167,94],[-291,-663],[-145,-8],[-148,-401],[-627,146],[96,383],[-118,72],[-668,102],[-329,-198],[-543,-36],[-402,149],[282,396],[85,227],[115,640],[120,435],[-586,216],[-264,221],[97,96]],[[78497,37080],[88,410],[147,103],[205,299],[70,-77],[316,339],[97,-93],[403,372],[628,1056],[415,-266],[261,1172]],[[73714,33776],[251,125],[366,457],[173,399],[254,274],[74,-59],[932,1148],[471,649],[316,-91],[382,-32],[-99,-411],[568,-159],[567,-224],[145,492],[219,-71],[164,807]],[[47258,71517],[107,-188],[-229,-228],[-270,-74],[-154,-158],[106,-306],[180,-96],[4,-285],[-444,125],[-397,-246],[-711,320],[-43,-159],[-190,-90],[-148,-255],[85,-102],[-225,-310],[-188,-451],[-524,-577],[-258,-332],[-426,-271],[-365,-392],[-436,-331],[-38,-173],[-263,-419],[-314,-278],[560,-323],[74,-148],[-90,-133],[195,-249],[-116,-371],[-59,-653],[-125,-371],[-238,-437],[430,-193],[222,-434],[9,-153],[266,-44],[278,-326],[73,-300],[168,-258],[164,4],[558,-330],[142,-305],[514,-333],[-190,-121],[-834,-708],[548,-613],[-68,-54],[500,-583],[533,-763],[222,143],[1045,-643],[26,-79],[-566,-504],[540,-777],[-213,-167],[120,-182]],[[52876,60644],[28,603],[-27,206],[-232,473],[341,876],[559,1613],[-287,-102],[-53,-256],[-175,-267],[-309,-13],[-180,-379],[-217,-28],[-140,83],[-151,240],[114,366],[199,224],[-149,268],[-406,139],[-178,-352],[-178,-102],[-202,121],[-195,272],[-339,148],[-171,-315],[-178,88],[-120,647],[-203,286],[-63,454],[131,109],[-46,203],[342,263],[17,293],[134,521],[245,155],[122,-12],[31,439],[-122,123],[55,152],[-194,464],[93,223],[-1974,1415],[-1201,1072],[-339,160]],[[64806,57290],[-994,-1936],[-999,-3727]],[[66503,60597],[-1697,-3307]],[[77078,52297],[-106,83],[-603,-13],[-146,44],[198,409],[-614,361],[-256,209],[59,123],[-287,207],[97,90],[-304,347],[29,86],[-249,882],[-243,53],[-579,241],[-613,340],[-445,334],[-64,193],[64,153],[-964,861],[-29,96],[-5520,3201]],[[72897,45067],[264,292],[57,343],[-109,801],[192,373],[-396,279],[1300,2307],[77,255],[212,216],[732,920],[129,299],[386,-229],[121,-169],[375,-234],[64,221],[173,229],[-9,148],[271,647],[305,359],[37,173]],[[61618,47169],[5426,-1585],[314,-358],[387,-207],[254,-2],[301,-247],[338,-468],[457,-392],[454,-457]],[[61700,47475],[-82,-306]],[[61618,47169],[-1918,-7156]],[[67611,32387],[-91,291],[-293,612],[-853,1702],[-270,405],[317,201],[-83,470],[-331,450],[-365,370],[390,399],[206,426],[-682,579],[452,640],[2252,2844],[1301,1661]],[[59700,40013],[-230,-858],[-931,-2488],[-244,-592],[2907,-1479],[50,-125],[-331,-228],[524,-634],[-324,-320],[36,-40],[-397,-463],[-42,-408],[268,-354],[888,475],[264,-536],[-330,-251],[-200,-306],[269,-198],[-445,-447],[93,-206],[577,-501]],[[39899,15244],[1323,1115],[741,497],[-443,633],[-270,-180],[-196,290],[-392,390],[48,312],[-200,257],[47,246]],[[36871,15457],[248,-443],[-201,-235],[398,-600],[906,906],[1199,870],[478,-711]],[[40557,18804],[-178,-90],[66,349],[-10,448],[-262,132],[-114,141],[-497,-250],[-239,497],[88,58],[-194,420],[-209,-64],[-223,574],[132,69],[-47,284],[421,255],[-641,204],[-196,173],[247,263],[-210,661],[-192,-74],[-415,932],[-93,75],[328,705],[-105,389],[38,84],[-419,581],[-597,1048]],[[77078,52297],[140,321],[133,129],[179,335],[375,299],[739,-317],[265,548],[1957,150],[445,-211],[515,-364],[31,32]],[[67999,63512],[-1496,-2915]],[[83220,55779],[-52,205]],[[81857,53219],[164,167],[232,371],[674,1252],[293,770]],[[11462,34380],[-12,400],[276,506],[-211,505],[18,163],[335,470],[89,229],[111,643],[335,248],[268,260],[-16,493],[-76,312],[125,210],[315,161]],[[15423,20404],[-4,454],[-132,699],[-141,432],[180,566],[193,294],[103,507],[-110,514],[-232,297],[-480,518],[-87,414],[-23,390],[-243,420],[-184,751],[-202,549],[-360,591],[-216,569],[361,611],[86,330],[-544,843],[-162,614],[-386,305],[-252,284],[-1123,746],[-206,1432],[-447,423],[-38,158],[411,193],[151,-47],[126,119]],[[13019,38980],[-119,448],[-129,227],[-423,287],[-404,45],[-262,106],[-254,-64],[-395,233],[-755,-515],[130,-128],[249,-697],[362,-340],[172,-491],[24,-251],[-261,-892],[-201,124],[-176,-4],[-46,134],[-336,52],[-85,124],[-210,-43],[-440,294],[-150,-30],[-526,135],[-114,-33],[-125,151],[-316,-149],[-543,175],[-268,-106],[-257,121],[-1275,-928],[-379,-555],[-498,-1020],[-393,-1227],[-229,-624],[-79,-116],[257,-635],[154,-119],[-38,-210],[195,-62],[408,-319],[-16,-97],[165,-363],[-240,-52],[-238,-295],[-231,-65],[-102,82],[-216,-290],[-130,85],[-44,-299],[-104,46],[-187,-259],[-106,93],[-205,-149],[-392,-140],[-115,-213],[-165,-99],[-11,-246],[-162,-210],[-100,-304],[2258,-1256],[1122,-579],[1918,-944],[-245,-315],[471,-477],[1183,-448],[244,-124],[420,51],[530,-549],[61,-418],[208,-462],[37,-199],[263,-254],[180,-273],[-33,-440],[-82,-209],[-310,-363],[-367,-589],[-85,60],[-201,-129],[-100,-398],[-141,-145],[219,-128],[141,-210]],[[50218,43264],[-671,-641],[-122,-207],[-457,-471],[126,-207],[-294,-297],[-195,192],[-231,-291],[-107,107],[-448,-685],[-269,156],[-328,285],[-234,-277],[231,-404],[-630,-689],[-589,-569],[-106,-37]],[[59700,40013],[-4801,1454],[-132,140],[-612,187],[-323,232],[-550,542],[-55,203],[-166,-570],[-734,297],[-472,149],[85,-418],[-112,-489],[-271,112],[-151,348],[-92,361],[-187,243],[-368,18],[-421,535],[-120,-93]],[[55801,20949],[149,-393],[261,-332],[319,-154],[353,-4],[385,257],[155,312],[32,590],[94,407],[648,1449],[42,378],[-29,297],[45,281],[327,351],[416,81],[358,-109],[426,-297]],[[43871,31011],[93,-508],[54,-31],[21,-1068],[61,-570],[83,-342],[114,-57],[1094,148],[7,-63],[1486,204],[36,-439],[-32,-217],[511,-110],[298,98],[701,442],[109,-22],[-158,-722],[76,-16],[-52,-329],[269,14],[-30,-1694],[-90,-1252]],[[45894,39229],[-989,-757],[343,-708],[286,-460],[201,-197],[629,-400],[-231,-73],[-163,-378],[-583,-1214],[-353,-510],[79,-56],[-699,-987],[-380,-815],[-267,-508],[146,-1149],[-42,-6]],[[64806,57290],[-4067,2358],[-91,25],[-1874,969],[-1315,577],[-1081,-516],[-681,142],[-1013,1115],[-421,-246],[-1392,-1102]],[[47808,51446],[-759,-766],[-174,-137],[134,-211],[-3401,-3431],[-544,567],[-392,-396],[-1041,-989]],[[50218,43264],[-788,959],[184,116],[564,516],[1021,661],[-145,139],[-517,663],[-139,253],[-194,190],[-805,1775],[-63,222],[-196,283]],[[44363,40479],[705,-851],[363,-171],[222,-20],[241,-208]],[[41631,46083],[58,-72],[-322,-149],[474,-708],[163,-130],[499,-239],[16,-381],[228,-710],[608,-1081],[-73,-109],[406,-756],[-149,-73],[166,-332],[658,-864]],[[85175,47791],[-13,-100],[307,-245],[640,-149],[179,13],[112,148],[396,39],[24,279],[-106,245],[144,573],[98,142],[397,10],[880,-696],[165,-168],[387,-638],[436,228],[370,88],[619,291],[1095,344],[358,71],[895,703],[317,290],[214,328],[329,807],[194,303],[163,5],[196,383],[451,728],[312,414],[125,249],[210,244],[236,76],[297,-174],[237,13],[250,254]],[[81857,53219],[2348,-1602],[-2,-72],[-869,-941],[-296,-517],[25,-44],[509,4],[798,180],[-48,-379],[-188,-422],[885,-711],[-295,-981],[251,37],[84,111],[116,-91]],[[96089,52889],[-283,80],[24,283],[-125,322],[-169,205],[11,358],[104,89],[-137,231],[385,259],[-27,165],[213,249],[100,274],[-80,335],[178,314],[-115,431],[-362,139],[-307,-260],[-340,-219],[-83,35],[-226,-394],[-27,-252],[-460,-873],[-917,-1104],[-881,-578],[495,-471],[-308,-283],[-954,-290],[-637,-439],[184,-435],[-249,-120],[-102,79],[-823,-311],[-224,-227],[-239,-103],[-192,-172],[-464,-177],[-268,-199],[-425,41],[-139,-153],[-368,-214],[-268,592],[-281,253],[-487,548],[-736,295],[-52,107],[213,405],[222,766],[-3243,3309]],[[81728,65708],[319,-45],[288,34],[209,168],[36,225],[187,-31],[31,178],[284,-35],[62,101],[-117,311],[140,130],[287,-22],[359,154],[84,272],[45,434],[305,299],[-148,185],[-23,384],[-136,77],[-344,-48],[-78,111],[265,404],[-140,252],[-129,38],[-238,-118],[-214,317],[-27,343],[165,156],[115,-51],[18,243],[135,340],[-458,-23],[-95,239],[250,158],[-264,265],[381,315],[-151,106],[-224,428],[-277,16],[85,285],[293,36],[195,373],[-24,159],[-244,-15],[-92,296],[-263,-10],[-403,174],[-127,401],[-131,18],[-310,-266],[-478,439],[-6091,3322],[-2720,-5298]],[[94576,39149],[625,350],[322,222],[298,374],[164,325],[651,1122],[551,1100],[488,1048],[160,295],[625,843],[473,816],[25,88],[820,1503],[221,485],[-107,612],[-154,163],[-44,364],[-120,373],[116,419],[106,613],[-34,110],[-326,228],[-677,307],[580,889],[40,465],[199,261],[23,148],[322,301],[-372,146],[-58,-43],[-487,19],[-255,-243],[-272,17],[-372,-389],[-437,-89],[-362,280],[-291,10],[-244,-81],[-169,112],[-425,44],[-90,133]],[[82035,40565],[150,89],[434,-313],[119,-183],[808,-1923],[191,245],[446,315],[134,21],[265,288],[291,-35],[20,-78],[333,-29],[201,182],[365,74],[297,-76],[314,162],[265,-18],[244,123],[396,-117],[323,-7],[665,-303],[643,485],[126,-12],[311,251],[271,130],[328,-102],[236,56],[186,178],[420,-512],[195,199],[240,445],[268,-132],[894,-306],[570,-60],[75,183],[243,-95],[466,162],[271,-52],[297,-282],[240,-369]],[[85175,47791],[-57,-53],[-315,-828],[-372,-217],[-309,-752],[-111,-455],[-101,-47],[-394,212],[-798,348],[-540,-1299],[-277,12],[-798,371],[-470,-1584],[4,-38],[609,-123],[-195,-1062],[23,-40],[1450,-458],[-489,-1213]],[[22458,7777],[384,329],[-209,582],[680,638],[166,-197],[422,331],[463,536],[355,-69],[377,-138],[229,-178],[490,-777],[231,-260],[399,745]],[[43625,19550],[205,-326],[452,-492],[61,79],[554,-592],[420,348],[269,66],[380,-27],[279,35],[105,-97],[-1,-213],[98,-241],[904,-659],[569,429],[470,-487],[45,15],[600,-426],[1021,-580],[124,419],[380,495],[353,-478],[-360,-305],[-249,-533],[88,-42],[567,77],[386,268],[259,-346],[271,-259],[-31,195],[110,178]],[[41629,28490],[296,-254],[174,-392],[502,-1011],[-52,-159],[439,-1073],[100,-54],[208,-555],[-360,-168],[260,-438],[69,-231],[-61,-122],[157,-304],[-30,-207],[115,71],[427,-646],[-324,-317],[59,-69],[-146,-505],[41,-391],[134,-437],[95,18],[532,-950],[-195,-3],[-146,-213],[-141,48],[-10,-219],[-268,-143],[121,-216]],[[43871,31011],[-465,-150],[-287,-255],[-347,-420],[-280,-518],[-863,-1178]],[[81127,40395],[69,164],[743,-245],[96,251]],[[32468,37433],[25,-30],[682,604],[509,-655],[678,635],[-181,233],[-129,31],[-261,336],[469,396],[139,239],[718,19],[422,-63],[548,-238],[438,-293],[519,526],[-92,127],[163,70],[266,-37],[80,164],[-54,649],[234,257],[4355,-1905],[572,635],[533,506],[207,-234],[294,336],[161,-21],[340,355],[-61,77],[321,327]],[[25999,43592],[531,-389],[597,-333],[708,-232],[223,-20],[568,-627],[1066,-1324],[484,-487],[449,-560],[1172,-1306],[671,-881]],[[41631,46083],[-103,-98],[-658,620],[-997,1116],[-521,618],[-59,-61],[-274,398],[-451,569],[-603,335],[-97,181],[-22,355],[-712,-485],[-1,102],[-308,354],[-204,-162],[-336,-523],[-154,177],[-683,-157],[-483,-495],[-185,193],[-456,-455],[-564,63],[-205,-253],[259,-359],[-213,-398],[-334,367],[-261,-373],[-188,165],[-190,-219],[-374,353],[-256,-78],[-623,973],[-238,305],[-213,465],[-543,-296],[-284,-28],[-493,-594],[-185,-319],[-261,-285],[-350,-214],[-389,-485],[-698,-964],[18,-58],[-314,-693],[-73,-257],[-382,-668],[-421,-476],[-160,107],[-390,-854]],[[41629,28490],[-541,-882],[-360,-507],[-224,-234],[-435,-227],[-578,-104],[-359,-4],[-565,114],[-355,155],[-433,275]],[[40557,18804],[646,362],[292,104],[1174,-39],[578,283],[378,36]],[[33321,8169],[159,-108],[1894,489],[2842,749]],[[33414,8297],[-93,-128]],[[40228,11713],[126,508],[-16,140],[330,413],[524,830],[-310,328],[-983,1312]],[[52071,16053],[-117,-2]],[[51537,10363],[126,606],[59,87],[-53,278],[-270,721],[-11,317],[175,1500],[508,2181]],[[81441,32124],[380,-244],[32,-199],[328,-256],[588,-147],[-97,370],[203,207],[504,372],[690,853],[195,-10],[314,339],[395,124],[652,315],[815,455],[236,183],[225,34],[390,176],[218,187],[306,65],[266,-123],[284,100],[302,189],[762,243],[591,125],[429,154],[663,616],[1511,1284],[959,758],[398,496],[596,359]],[[78497,37080],[617,-86],[448,-230],[273,537],[569,-329],[459,-189],[148,117],[634,-274],[135,-359],[541,-343],[-437,-915],[-281,-504],[-1114,-1096],[-61,-40],[-13,-576],[1026,-669]],[[75724,29820],[40,124],[363,279],[219,-135],[296,217],[132,-5],[-114,367],[601,16],[117,129],[-95,210],[126,156],[157,-61],[467,654],[204,-18],[191,210],[268,-55],[448,52],[73,-157],[189,-46],[381,-352],[580,-16],[-26,-118],[277,-103],[204,122],[117,-191],[90,119],[421,14],[87,56],[-96,836]],[[73714,33776],[46,-535],[78,-335],[184,-286],[912,-1053],[293,-543],[-57,-31],[554,-1173]],[[21657,29797],[-112,187],[-474,14],[-450,-155],[-329,49],[-89,125],[-713,282],[-165,-46],[-420,67],[-203,124],[-148,-145],[-295,104],[-192,-49],[-449,11],[-11,114],[-251,123],[-27,205],[-138,101],[-165,370],[-202,44],[-352,297],[-124,357],[-308,-40],[-421,-135],[-27,-266],[-331,233],[-45,600],[382,273],[-43,347],[-427,790],[384,224],[-330,560],[-469,-313],[-1205,-736],[-536,-45],[-173,120],[9,442],[-207,-39],[-240,79],[-333,-142],[-566,452]],[[25999,43592],[-1101,842],[-892,816],[-1441,1476],[-403,-402],[-597,-479],[-413,-514],[-306,-206],[-181,-195],[-149,35],[-160,-112],[-112,-366],[-338,-67],[-160,39],[-173,-193],[-215,-14],[-258,-131],[-423,-62],[-7,-139],[-307,-79],[-392,-17],[-272,180],[-276,-610],[-106,-52],[-535,308],[-182,-347],[179,-220],[33,-319],[-301,-240],[-317,66],[-310,172],[-152,-63],[208,-420],[-147,-260],[-478,-363],[-357,130],[-47,-285],[92,-204],[1,-451],[63,-242],[-666,-197],[-385,-280],[-174,-196],[-396,-768],[-427,-183]],[[33559,31026],[-22,226],[-367,109],[-228,508],[190,269],[-7,326],[262,577],[55,334],[-382,543],[-107,34],[-223,-124],[-468,910],[928,686],[142,205],[269,222],[208,95],[-202,200],[-726,475],[-633,617],[220,195]],[[19084,4777],[54,-78],[361,11],[261,-130],[310,-43],[327,167],[-68,-300],[225,-158],[174,98],[54,-173],[184,-63],[113,159],[163,8],[45,-347],[-79,-256],[382,294],[76,-80],[-159,-284],[120,-93],[214,63],[-76,-259],[66,-312],[191,146],[79,-86],[-100,-222],[173,-619],[125,-170],[151,747],[118,385],[255,456],[609,666],[524,167],[253,317],[127,258],[719,-632],[523,757],[203,187],[-158,162],[448,1940],[1079,1791],[2354,-114],[3262,-591],[555,-377]],[[64854,20141],[95,109],[238,-3],[-74,766],[201,168],[338,-50],[-163,324],[29,86],[254,-104],[62,-139],[210,129],[140,-47],[180,93],[136,307],[170,-41],[172,268],[307,109],[-9,158],[221,30],[-59,234],[78,85],[153,-99],[125,71],[41,-157],[251,-11],[192,-168],[358,612],[-101,114],[102,165],[498,481],[235,43],[43,500],[279,505],[332,-15],[-25,124],[308,221],[-90,357],[192,84],[13,366],[140,-85],[329,315],[251,32],[303,153],[350,16],[266,-76],[47,-107],[282,155],[-177,86],[337,439],[-41,84],[311,-21],[67,-137],[114,297],[451,203],[127,668],[204,288],[57,276],[274,72],[-13,215],[102,49],[233,-112],[270,51],[283,157],[231,-13],[-25,203],[-144,193],[75,316],[551,257],[183,30]],[[63501,20657],[621,-74],[374,-89],[358,-353]],[[73676,33768],[-380,-190],[-136,-12],[-141,142],[-161,348],[-458,325],[-190,-38],[-256,-213],[-320,-149],[-776,-139],[-382,-129],[-347,-183],[-163,-226]],[[53476,6982],[675,1241],[218,73],[536,373],[731,439],[972,174],[205,300],[453,207],[1179,618],[1337,751],[605,2],[444,69],[540,177],[332,242]],[[61703,11648],[-169,272],[-72,-20],[-448,721],[-1296,-207],[-3,22],[-1332,-210],[-1848,1924],[440,595],[-534,252],[-449,486],[-181,-325],[-757,607],[-654,478],[-355,5],[-110,-85],[-805,85],[-161,-89],[-309,22],[-304,-127],[-70,155],[-215,-156]],[[69050,65560],[-7885,4572],[-865,183],[-524,263],[-1580,865],[-1730,647],[-757,796],[-1712,1054],[-1028,602],[16,290],[-1299,1145],[-380,376],[-300,536],[34,165],[-1044,1006],[-200,369],[-271,294],[177,404],[-791,406],[206,326],[-239,215],[-437,-95],[-39,-309],[36,-335],[-158,-220],[-263,-190],[33,-191],[-222,-138],[-195,-291],[-301,7],[20,-123],[-174,-188],[138,-225],[-97,-207],[21,-208],[-154,-247],[174,-373],[-131,-37],[25,-497],[-180,-260],[343,-124],[85,-291],[-58,-322],[-183,-7],[-137,-191],[54,-137],[171,-51],[-5,-165],[-197,-246],[106,-242],[-184,-80],[-152,-268],[90,-409],[306,-451],[286,12],[126,-410],[12,-339],[-207,-211],[-299,-200],[-24,-108],[151,-190]],[[61703,11648],[639,467],[238,389],[1414,1051],[610,514],[621,681],[279,265],[-197,1538],[-244,1738],[-159,285],[-52,310],[67,520],[-101,336],[178,119],[-142,280]]],"transform":{"scale":[0.005101784449074007,-0.004800048000480005],"translate":[224.91332843852422,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/gl.json b/src/onegov/election_day/static/mapdata/2025/gl.json new file mode 100644 index 0000000000..875a9c5e2f --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/gl.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":1630,"properties":{"id":1630,"name":"Glarus Nord"},"arcs":[[-1,-2,-3]]},{"type":"Polygon","id":1631,"properties":{"id":1631,"name":"Glarus Süd"},"arcs":[[-4,0,-5]]},{"type":"Polygon","id":1632,"properties":{"id":1632,"name":"Glarus"},"arcs":[[-6,1,3]]}]}},"arcs":[[[67807,65075],[1049,-202]],[[18766,66872],[483,-198],[285,-18],[292,-300],[266,-68],[923,64],[707,-56],[398,-102],[353,156],[297,-11],[846,172],[374,-14],[1784,112],[243,79],[270,276],[275,57],[522,409],[564,348],[473,386],[304,102],[337,240],[119,201],[583,246],[337,272],[388,443],[1657,283],[592,14],[577,142],[622,-63],[1162,210],[616,237],[2470,567],[97,92],[850,198],[288,14],[189,122],[67,232],[344,502],[-62,353],[80,371],[400,265],[540,109],[473,469],[268,89],[191,502],[-14,176],[397,250],[905,-32],[389,66],[902,365],[358,35],[333,182],[610,-121],[274,0],[82,472],[296,121],[131,-143],[473,35],[94,-812],[876,30],[62,61],[494,-512],[124,-2123],[95,-44],[480,561],[491,-297],[369,-341],[650,-167],[142,175],[193,528],[405,-167],[3,269],[-449,116],[-38,239],[455,85],[660,-88],[622,-10],[511,116],[-88,89],[375,45],[357,-54],[373,-217],[733,44],[651,-137],[505,56],[965,-343],[171,-240],[502,51],[1089,-59],[1180,-199],[1102,131],[143,-155],[9,-252],[293,-376],[236,-103],[304,210],[655,133],[471,-59],[272,-425],[-131,-457],[-398,-352],[-74,-444],[670,216],[669,151],[944,-299],[1016,373],[389,-216],[-899,-1626],[-285,-1598],[502,-136],[382,-583],[1,-465],[220,-178],[85,-280],[513,-381],[920,-191]],[[68856,64873],[2929,1557],[152,207],[311,174],[414,112],[152,159],[682,167],[707,98],[262,233],[1524,250],[502,-130],[353,134],[208,349],[448,370],[564,11],[274,96],[526,480],[668,445],[294,292],[387,113],[102,253],[325,154],[184,488],[199,286],[-105,92],[146,427],[487,321],[790,1194],[149,607],[220,110],[36,264],[-352,91],[49,129],[-29,828],[-563,1788],[-35,375],[202,488],[-22,191],[213,563],[196,135],[-471,-27],[-223,473],[-270,375],[-137,496],[-252,402],[-32,666],[145,186],[8,403],[262,170],[172,275],[65,568],[-190,279],[413,645],[29,186],[-297,421],[74,52],[-150,979],[217,2094],[-11129,1210],[-3121,763],[-5392,125],[-1618,-394],[-771,44],[-616,179],[-519,219],[-280,18],[-256,-118],[-1578,-293],[-316,-17],[-6029,-584],[-271,-1],[-662,274],[-554,546],[-2774,1603],[-847,613],[-5890,4094],[-6198,4301],[-3182,-2768],[-395,-405],[-615,-715],[-3535,-4165],[-224,-197],[100,-250],[-248,-495],[-514,-475],[-301,-97],[-837,-437],[275,-225],[262,-331],[-315,-269],[141,-568],[134,-304],[-178,-141],[-117,-349],[-56,-477],[-352,-431],[-88,-415],[-179,-350],[36,-150],[500,-602],[173,-10],[608,-228],[479,-26],[286,-333],[209,-458],[-146,-354],[-548,-360],[54,-630],[-481,-366],[289,-445],[275,-616],[-160,-231],[-353,-80],[-492,-213],[-825,-202],[-221,-257],[-139,8],[-822,-236],[-201,-229],[-199,-390],[-228,-71],[-107,-482],[-419,-356],[-260,-63],[-52,-734],[200,-222],[516,20],[191,-222],[929,-65],[990,-334],[247,-26],[833,-249],[1255,-60],[208,-163],[277,34],[215,-162],[-692,-312],[-955,-529],[-413,-297],[-424,-29],[99,-422],[-423,-438],[-751,-456],[-358,-68],[347,-396],[-25,-408],[-100,-185],[61,-296],[-165,-198],[-307,22],[-230,-227],[-266,-596],[-461,-484],[-502,-213],[66,-121],[-400,-409],[-94,-439],[-400,-208],[-172,-689],[-161,-108],[-122,-297],[127,-107],[30,-291],[-225,-360],[54,-461],[-212,-678]],[[67807,65075],[-47,-395],[-762,-342],[-263,-211],[-204,-440],[-426,-385],[-241,-300],[-333,-216],[-235,-759],[-301,-191],[80,-191],[-233,-63],[161,-577],[-129,-259],[-241,-58],[-397,-397],[-514,-382],[-399,-208],[-335,-422],[-134,-297],[-206,-199],[-11,-284],[-532,-332],[-396,-34],[-703,389],[-457,162],[-865,64],[-210,72],[155,240],[99,607],[-647,167],[-548,-533],[-818,2],[-161,95],[-409,10],[-587,-250],[-421,-41],[-419,-158],[-80,-285],[-661,402],[-292,658],[-127,669],[-592,284],[-61,202],[439,565],[-53,235],[-186,89],[-664,140],[-425,254],[54,252],[-153,25],[-25,-389],[-332,126],[-193,-31],[-316,-267],[-416,161],[-354,13],[140,-100],[-1977,-879],[-157,-109],[-739,-198],[-254,-170],[-1475,-205],[-326,197],[-369,-87],[-358,19],[-1025,-433],[-539,-125],[-508,-48],[-224,66],[-586,-570],[-453,-547],[-236,-182],[69,-139],[-672,-498],[-639,-246],[-518,37],[-275,-137],[-492,-86],[-332,-134],[-917,-179],[-1158,-786],[12,-353],[-1125,-463],[-1328,-329],[-271,-387],[1,-143],[-897,-232],[-282,-162],[-670,-271],[-242,-293],[11,-264],[-323,-307],[-256,-116],[-72,-291],[-402,-384],[-1485,-448],[-23,-483],[-991,-573],[-49,-115],[-498,-300],[-398,-169],[-60,-132],[-367,-102],[-243,-750],[98,-109],[-105,-390],[-180,-69],[65,-325],[-143,-99],[-518,-98],[-305,-136],[-685,-126],[-174,-93],[-792,-219],[-224,-170],[-653,-204],[-537,-258],[-268,-235],[-648,-252],[-342,29],[-580,-389],[-635,-180],[-303,-20],[-548,-322]],[[19826,45791],[-67,-258],[-220,-93],[259,-65],[81,-247],[281,-41],[204,-184],[316,-81],[250,-446],[480,-304],[370,-156],[428,-45],[528,-186],[229,31],[445,-150],[588,13],[240,-152],[626,-172],[217,54],[269,-79],[292,83],[-133,-378],[-522,-155],[-232,-152],[-230,75],[-274,-320],[-369,-108],[-127,-237],[-348,-135],[-164,-220],[-113,-489],[-8,-675],[-121,-572],[-369,-116],[-22,-277],[-418,-442],[-184,-327],[69,-80],[-268,-491],[36,-130],[-348,-360],[174,-289],[13,-262],[471,-260],[192,-340],[-435,11],[155,-237],[700,-643],[298,122],[430,-168],[365,-520],[38,-190],[-235,-418],[-355,-116],[-215,48],[-404,-148],[-456,83],[-114,-199],[-400,128],[-393,-34],[-286,-210],[-447,-45],[-269,101],[-607,-14],[-137,-348],[-484,-114],[-383,-165],[-280,-247],[-672,54],[-437,-171],[-45,-152],[-246,-6],[-61,-219],[-423,-21],[-172,-118],[632,-979],[609,-1012],[673,-663],[347,-934],[584,-313],[319,-593],[455,-279],[850,13],[431,-238],[-140,-620],[362,-354],[-42,-131],[176,-533],[464,-1078],[-7,-101],[304,-548],[-121,-421],[322,-1797],[-468,-1108],[-1447,-588],[-488,-64],[-272,-173],[-420,-55],[-141,-196],[-949,-147],[-279,-246],[-801,-497],[-430,-158],[-651,-594],[-488,18],[-174,-116],[-1101,-219],[-929,-257],[-1267,-665],[-116,-98],[-507,-87],[-578,-19],[-641,36],[-491,175],[-483,-208],[-398,-413],[-597,-411],[-247,-276],[-336,-166],[-341,-275],[51,-102],[-252,-250],[-43,-173],[-610,-414],[-284,-249],[-15,-125],[-672,-149],[-306,-142],[-816,-80],[-686,-264],[-583,-293],[-820,-280],[-327,-46],[-488,-250],[-644,-119],[-464,-348],[-416,-116],[289,-157],[298,-450],[-101,-269],[259,-494],[-49,-409],[734,-447],[1231,-1149],[-325,-2381],[-1013,-842],[-174,-260],[414,-800],[1821,345],[315,-64],[872,156],[505,-79],[259,-182],[1859,243],[518,-189],[-79,-271],[283,-185],[891,-228],[473,-34],[154,-158],[436,49],[1103,300],[598,-42],[-190,-674],[157,-145],[28,-336],[225,-327],[-215,-145],[-52,-514],[-247,-230],[-22,-183],[182,-233],[343,-197],[140,-180],[601,-215],[505,-45],[962,64],[804,-134],[380,-334],[444,230],[824,124],[495,246],[1415,216],[325,333],[417,245],[484,199],[725,23],[815,105],[210,246],[457,364],[388,7],[789,-134],[839,296],[761,102],[473,178],[860,-25],[600,160],[774,68],[846,140],[895,-107],[804,241],[511,104],[576,-28],[812,146],[1307,410],[769,148],[2676,131],[2849,1663],[340,1171],[1037,1058],[485,1128],[504,542],[161,286],[463,326],[683,301],[-208,977],[623,985],[349,631],[547,574],[741,389],[745,262],[168,260],[-294,739],[-82,400],[-162,148],[72,871],[129,322],[-17,1310],[832,557],[811,134],[278,137],[499,81],[241,255],[466,240],[218,333],[803,658],[932,380],[278,-103],[239,51],[388,-65],[981,190],[403,-73],[470,56],[501,-44],[521,-239],[1351,-328],[163,-151],[699,38],[624,-150],[343,-15],[533,-158],[522,-40],[-148,-430],[105,-439],[547,-358],[1192,-1163],[685,-529],[110,-995],[155,-623],[125,-284],[1201,-418],[523,-111],[327,76],[60,173],[312,254],[803,227],[50,103],[698,385],[637,0],[358,143],[430,35],[392,306],[350,589],[651,241],[427,-12],[337,81],[621,357],[480,143],[692,40],[-23,445],[271,150],[79,430],[611,433],[81,300],[-40,250],[525,470],[633,325],[392,54],[478,-83],[1183,485],[-1051,1544],[838,-105],[382,80],[955,-69],[4286,-1],[1284,-125],[1052,-260],[533,-278],[125,274],[714,348],[995,266],[96,101],[576,154],[541,18],[738,660],[353,4],[490,973],[244,174],[421,161],[629,359],[490,710],[280,-57],[183,167],[-42,149],[859,601],[346,442],[501,367],[265,382],[568,527],[157,525],[271,280],[72,276],[500,170],[636,134],[372,207],[217,31],[351,202],[508,55],[850,-135],[315,310],[175,513],[523,423],[290,515],[683,231],[330,180],[65,460],[208,528],[374,506],[15,357],[-341,316],[373,384],[222,382],[-27,233],[-342,374],[-1,611],[-117,68],[-193,711],[-390,263],[-976,386],[-1039,318],[-572,243],[42,309],[117,60],[-237,171],[-287,436],[-52,193],[-377,263],[15,344],[162,346],[3,286],[-118,182],[68,383],[-35,400],[-99,169],[37,458],[204,104],[1530,315],[346,116],[340,673],[-65,203],[-354,451],[-522,1127],[173,779],[98,128],[26,520],[264,140],[9,402],[231,110],[177,488],[-131,912],[-286,138],[-380,373],[-93,396],[325,336],[65,375],[201,118],[143,596],[-234,223],[-16,556],[-129,79],[64,319],[336,321],[165,334],[612,159],[-105,213],[28,511],[-405,587],[-236,175],[-382,540],[-306,171],[-80,347],[-329,268],[-151,341],[18,183],[-160,209],[-2,682],[-56,301],[126,489],[-40,249],[-226,261],[-216,397],[-158,10],[-413,621],[-627,411],[-97,577],[-505,50],[-538,229],[-635,180],[-360,237],[-139,411],[-762,376],[-263,270],[-495,247],[-174,213],[-511,132],[-290,-52],[-332,53],[-434,-94],[-832,181],[-73,164],[-301,165],[-480,103],[-188,126],[-595,-44],[-365,-236],[-227,-19],[-733,108],[-1249,-522],[-393,-88],[-143,-194],[-761,-282],[-921,-566],[-328,-77],[-892,-486],[-798,-300],[-517,87],[-339,156],[-567,498],[-300,-77],[-478,-266],[-683,-255],[-340,-20],[-695,71],[-312,132],[-90,192],[-1664,635],[-282,-173],[-148,49],[-2057,953],[-2818,1340]],[[18766,66872],[-230,-109],[-455,39],[-86,-108],[-803,-271],[-296,-36],[-598,-520],[-43,-224],[-382,-314],[-575,-155],[-115,-103],[-975,-181],[-765,-329],[-772,-287],[-301,-274],[-385,-140],[-1025,-113],[-64,112],[-665,37],[-198,369],[-677,-173],[-700,93],[-438,-116],[-415,-234],[-560,71],[-225,-46],[-434,-246],[-211,-261],[-17,-357],[206,-500],[-107,-365],[670,-696],[-49,-148],[147,-405],[-748,-303],[-744,-81],[-666,-151],[-19,-361],[-594,-96],[78,-203],[456,-514],[448,59],[166,-120],[751,113],[1404,-603],[1351,-415],[179,-354],[-104,-366],[265,-1182],[8,-251],[1026,-346],[443,-545],[13,-529],[586,-558],[468,-328],[129,358],[321,-92],[139,-164],[702,-415],[557,-238],[473,-392],[222,-449],[242,-275],[252,-658],[391,-183],[52,-226],[377,-215],[212,90],[82,-275],[398,-403],[183,260],[770,61],[-133,-761],[-494,-204],[-1772,-463],[835,-855],[2821,-3099],[502,275],[288,251],[287,115]]],"transform":{"scale":[0.0032928983593636736,-0.004800048000480004],"translate":[315.356728480996,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/gr.json b/src/onegov/election_day/static/mapdata/2025/gr.json new file mode 100644 index 0000000000..293b799b51 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/gr.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":3506,"properties":{"id":3506,"name":"Vaz/Obervaz"},"arcs":[[-1,-2,-3,-4,-5,-6,-7,-8,-9]]},{"type":"Polygon","id":3513,"properties":{"id":3513,"name":"Lantsch/Lenz"},"arcs":[[-10,-11,4]]},{"type":"Polygon","id":3514,"properties":{"id":3514,"name":"Schmitten (GR)"},"arcs":[[-12,-13,-14,-15]]},{"type":"Polygon","id":3542,"properties":{"id":3542,"name":"Albula/Alvra"},"arcs":[[-16,-17,5,10,-18,11,-19,-20]]},{"type":"Polygon","id":3543,"properties":{"id":3543,"name":"Surses"},"arcs":[[19,-21,-22,-23,-24,-25,-26,-27,-28,-29]]},{"type":"Polygon","id":3544,"properties":{"id":3544,"name":"Bergün Filisur"},"arcs":[[-30,20,18,14,-31,-32,-33,-34,-35]]},{"type":"Polygon","id":3551,"properties":{"id":3551,"name":"Brusio"},"arcs":[[-36,-37]]},{"type":"Polygon","id":3561,"properties":{"id":3561,"name":"Poschiavo"},"arcs":[[-38,-39,36,-40]]},{"type":"Polygon","id":3572,"properties":{"id":3572,"name":"Falera"},"arcs":[[-41,-42,-43]]},{"type":"Polygon","id":3575,"properties":{"id":3575,"name":"Laax"},"arcs":[[-44,-45,41,-46,-47]]},{"type":"Polygon","id":3581,"properties":{"id":3581,"name":"Sagogn"},"arcs":[[-48,-49,-50,44,-51]]},{"type":"Polygon","id":3582,"properties":{"id":3582,"name":"Schluein"},"arcs":[[42,49,-52]]},{"type":"Polygon","id":3603,"properties":{"id":3603,"name":"Vals"},"arcs":[[-53,-54,-55,-56]]},{"type":"Polygon","id":3618,"properties":{"id":3618,"name":"Lumnezia"},"arcs":[[-57,-58,-59,53,-60,-61]]},{"type":"Polygon","id":3619,"properties":{"id":3619,"name":"Ilanz/Glion"},"arcs":[[51,48,-62,58,-63,-64,-65,45,40]]},{"type":"Polygon","id":3633,"properties":{"id":3633,"name":"Fürstenau"},"arcs":[[-66,-67,-68,-69,-70]]},{"type":"Polygon","id":3637,"properties":{"id":3637,"name":"Rothenbrunnen"},"arcs":[[-71,-72,-73,-74]]},{"type":"Polygon","id":3638,"properties":{"id":3638,"name":"Scharans"},"arcs":[[8,-75,65,-76]]},{"type":"Polygon","id":3640,"properties":{"id":3640,"name":"Sils im Domleschg"},"arcs":[[-77,66,74,7,-78,-79]]},{"type":"Polygon","id":3661,"properties":{"id":3661,"name":"Cazis"},"arcs":[[-80,-81,-82,72,-83,68,-84,-85]]},{"type":"MultiPolygon","id":3662,"properties":{"id":3662,"name":"Flerden"},"arcs":[[[-86,79,-87,-88]],[[-89,-90,-91]]]},{"type":"Polygon","id":3663,"properties":{"id":3663,"name":"Masein"},"arcs":[[-92,86,84,-93]]},{"type":"MultiPolygon","id":3668,"properties":{"id":3668,"name":"Thusis"},"arcs":[[[16,-94,77,6]],[[92,83,67,76,-95,-96,-97,-98]]]},{"type":"Polygon","id":3669,"properties":{"id":3669,"name":"Tschappina"},"arcs":[[-99,89,-100,-101,85]]},{"type":"Polygon","id":3670,"properties":{"id":3670,"name":"Urmein"},"arcs":[[90,98,87,91,97,-102]]},{"type":"Polygon","id":3672,"properties":{"id":3672,"name":"Safiental"},"arcs":[[80,100,-103,-104,-105,54,61,47,-106,-107,-108,-109]]},{"type":"Polygon","id":3673,"properties":{"id":3673,"name":"Domleschg"},"arcs":[[75,69,82,71,-110,-111,0]]},{"type":"Polygon","id":3681,"properties":{"id":3681,"name":"Avers"},"arcs":[[-112,-113,-114,-115,-116,25]]},{"type":"Polygon","id":3695,"properties":{"id":3695,"name":"Sufers"},"arcs":[[-117,103,-118,-119,-120,-121]]},{"type":"Polygon","id":3701,"properties":{"id":3701,"name":"Andeer"},"arcs":[[-122,-123,27,-124,118]]},{"type":"Polygon","id":3711,"properties":{"id":3711,"name":"Rongellen"},"arcs":[[-125,95,-126]]},{"type":"Polygon","id":3712,"properties":{"id":3712,"name":"Zillis-Reischen"},"arcs":[[28,122,-127,125,94,78,93,15]]},{"type":"MultiPolygon","id":3713,"properties":{"id":3713,"name":"Ferrera"},"arcs":[[[119,123,26,115,-128]],[[113,-129]]]},{"type":"Polygon","id":3714,"properties":{"id":3714,"name":"Rheinwald"},"arcs":[[-130,-131,-132,55,104,116]]},{"type":"Polygon","id":3715,"properties":{"id":3715,"name":"Muntogna da Schons"},"arcs":[[102,99,88,101,96,124,126,121,117]]},{"type":"Polygon","id":3721,"properties":{"id":3721,"name":"Bonaduz"},"arcs":[[-133,-134,107,-135,-136]]},{"type":"Polygon","id":3722,"properties":{"id":3722,"name":"Domat/Ems"},"arcs":[[-137,-138,-139,-140,109,70,-141,132]]},{"type":"Polygon","id":3723,"properties":{"id":3723,"name":"Rhäzüns"},"arcs":[[73,81,108,133,140]]},{"type":"Polygon","id":3731,"properties":{"id":3731,"name":"Felsberg"},"arcs":[[137,-142,-143,-144]]},{"type":"Polygon","id":3732,"properties":{"id":3732,"name":"Flims"},"arcs":[[-145,-146,105,50,43]]},{"type":"Polygon","id":3733,"properties":{"id":3733,"name":"Tamins"},"arcs":[[-147,141,136,135,-148]]},{"type":"Polygon","id":3734,"properties":{"id":3734,"name":"Trin"},"arcs":[[147,134,106,145,-149]]},{"type":"Polygon","id":3746,"properties":{"id":3746,"name":"Zernez"},"arcs":[[-150,-151,-152,-153,-154,-155,-156]]},{"type":"Polygon","id":3752,"properties":{"id":3752,"name":"Samnaun"},"arcs":[[-157,-158]]},{"type":"Polygon","id":3762,"properties":{"id":3762,"name":"Scuol"},"arcs":[[-159,-160,-161,-162,-163,149,-164]]},{"type":"MultiPolygon","id":3764,"properties":{"id":3764,"name":"Valsot"},"arcs":[[[160,-165,157,-166]],[[-167,158]]]},{"type":"MultiPolygon","id":3781,"properties":{"id":3781,"name":"Bever"},"arcs":[[[-168,-169,-170,21,29]],[[-171,-172]]]},{"type":"Polygon","id":3782,"properties":{"id":3782,"name":"Celerina/Schlarigna"},"arcs":[[-173,-174,-175,-176]]},{"type":"MultiPolygon","id":3783,"properties":{"id":3783,"name":"Madulain"},"arcs":[[[-177,-178,-179,-180]],[[-181,-182,-183]]]},{"type":"Polygon","id":3784,"properties":{"id":3784,"name":"Pontresina"},"arcs":[[182,-184,-185,37,-186,-187,175,-188,-189]]},{"type":"Polygon","id":3785,"properties":{"id":3785,"name":"La Punt Chamues-ch"},"arcs":[[188,-190,171,33,-191,177,-192,180]]},{"type":"MultiPolygon","id":3786,"properties":{"id":3786,"name":"Samedan"},"arcs":[[[-193,-194,-195,172,186,-196]],[[34,170,189,187,174,-197,167]]]},{"type":"Polygon","id":3787,"properties":{"id":3787,"name":"St. Moritz"},"arcs":[[196,173,194,-198,168]]},{"type":"Polygon","id":3788,"properties":{"id":3788,"name":"S-chanf"},"arcs":[[179,-199,31,-200,152,-201,-202]]},{"type":"Polygon","id":3789,"properties":{"id":3789,"name":"Sils im Engadin/Segl"},"arcs":[[-203,-204,23,-205,192]]},{"type":"Polygon","id":3790,"properties":{"id":3790,"name":"Silvaplana"},"arcs":[[204,22,169,197,193]]},{"type":"MultiPolygon","id":3791,"properties":{"id":3791,"name":"Zuoz"},"arcs":[[[201,-206,183,181,191,176]],[[198,178,190,32]]]},{"type":"Polygon","id":3792,"properties":{"id":3792,"name":"Bregaglia"},"arcs":[[24,203,-207,111]]},{"type":"Polygon","id":3804,"properties":{"id":3804,"name":"Buseno"},"arcs":[[-208,-209,-210,-211,-212]]},{"type":"Polygon","id":3805,"properties":{"id":3805,"name":"Castaneda"},"arcs":[[-213,-214,-215,207]]},{"type":"Polygon","id":3808,"properties":{"id":3808,"name":"Rossa"},"arcs":[[-216,-217,-218,-219]]},{"type":"Polygon","id":3810,"properties":{"id":3810,"name":"Santa Maria in Calanca"},"arcs":[[211,-220,-221,212]]},{"type":"Polygon","id":3821,"properties":{"id":3821,"name":"Lostallo"},"arcs":[[-222,-223,-224,-225,-226,-227]]},{"type":"Polygon","id":3822,"properties":{"id":3822,"name":"Mesocco"},"arcs":[[130,-228,-229,215,-230]]},{"type":"Polygon","id":3823,"properties":{"id":3823,"name":"Soazza"},"arcs":[[-231,216,228,-232,221]]},{"type":"Polygon","id":3831,"properties":{"id":3831,"name":"Cama"},"arcs":[[-233,224,-234,-235]]},{"type":"MultiPolygon","id":3832,"properties":{"id":3832,"name":"Grono"},"arcs":[[[-236,-237,213,220,-238,225,232]],[[-239,233,223]]]},{"type":"Polygon","id":3834,"properties":{"id":3834,"name":"Roveredo (GR)"},"arcs":[[214,236,-240,-241,-242,-243,208]]},{"type":"MultiPolygon","id":3835,"properties":{"id":3835,"name":"San Vittore"},"arcs":[[[-244,209,242,-245]],[[240,-246]]]},{"type":"Polygon","id":3837,"properties":{"id":3837,"name":"Calanca"},"arcs":[[219,210,243,-247,217,230,226,237]]},{"type":"Polygon","id":3847,"properties":{"id":3847,"name":"Val Müstair"},"arcs":[[150,162,-248]]},{"type":"Polygon","id":3851,"properties":{"id":3851,"name":"Davos"},"arcs":[[-249,153,199,30,13,-250]]},{"type":"Polygon","id":3861,"properties":{"id":3861,"name":"Fideris"},"arcs":[[-251,-252,-253,-254]]},{"type":"Polygon","id":3862,"properties":{"id":3862,"name":"Furna"},"arcs":[[-255,-256,-257,-258,-259]]},{"type":"Polygon","id":3863,"properties":{"id":3863,"name":"Jenaz"},"arcs":[[-260,-261,251,-262,254]]},{"type":"Polygon","id":3871,"properties":{"id":3871,"name":"Klosters"},"arcs":[[-263,154,248,-264,-265,-266,-267]]},{"type":"Polygon","id":3881,"properties":{"id":3881,"name":"Conters im Prättigau"},"arcs":[[253,-268,264,-269]]},{"type":"Polygon","id":3882,"properties":{"id":3882,"name":"Küblis"},"arcs":[[-270,265,267]]},{"type":"Polygon","id":3891,"properties":{"id":3891,"name":"Luzein"},"arcs":[[266,269,252,260,-271,-272]]},{"type":"Polygon","id":3901,"properties":{"id":3901,"name":"Chur"},"arcs":[[138,143,-273,-274,-275,-276,2,-277]]},{"type":"Polygon","id":3911,"properties":{"id":3911,"name":"Churwalden"},"arcs":[[276,1,110,139]]},{"type":"Polygon","id":3921,"properties":{"id":3921,"name":"Arosa"},"arcs":[[3,275,-278,255,261,250,268,263,249,12,17,9]]},{"type":"Polygon","id":3945,"properties":{"id":3945,"name":"Trimmis"},"arcs":[[-279,-280,256,277,274,-281]]},{"type":"Polygon","id":3946,"properties":{"id":3946,"name":"Untervaz"},"arcs":[[280,273,-282,-283,-284]]},{"type":"Polygon","id":3947,"properties":{"id":3947,"name":"Zizers"},"arcs":[[-285,278,283,-286,-287]]},{"type":"MultiPolygon","id":3951,"properties":{"id":3951,"name":"Fläsch"},"arcs":[[[-288,-289],[-290]],[[-291,-292]]]},{"type":"Polygon","id":3952,"properties":{"id":3952,"name":"Jenins"},"arcs":[[-293,-294,-295]]},{"type":"MultiPolygon","id":3953,"properties":{"id":3953,"name":"Maienfeld"},"arcs":[[[-296,293,-297,-298,-299,-300,287,-301,291,-302]],[[289]]]},{"type":"Polygon","id":3954,"properties":{"id":3954,"name":"Malans"},"arcs":[[296,292,-303,-304]]},{"type":"MultiPolygon","id":3955,"properties":{"id":3955,"name":"Landquart"},"arcs":[[[286,297,303,-305]],[[298,285,282,-306]]]},{"type":"Polygon","id":3961,"properties":{"id":3961,"name":"Grüsch"},"arcs":[[304,-307,-308,257,279,284]]},{"type":"Polygon","id":3962,"properties":{"id":3962,"name":"Schiers"},"arcs":[[258,307,-309,-310,270,259]]},{"type":"Polygon","id":3972,"properties":{"id":3972,"name":"Seewis im Prättigau"},"arcs":[[306,302,294,295,-311,308]]},{"type":"Polygon","id":3981,"properties":{"id":3981,"name":"Breil/Brigels"},"arcs":[[-312,-313,63,-314]]},{"type":"Polygon","id":3982,"properties":{"id":3982,"name":"Disentis/Mustér"},"arcs":[[-315,-316,-317,-318]]},{"type":"Polygon","id":3983,"properties":{"id":3983,"name":"Medel (Lucmagn)"},"arcs":[[-319,60,-320,-321,314]]},{"type":"Polygon","id":3985,"properties":{"id":3985,"name":"Sumvitg"},"arcs":[[318,317,-322,-323,-324,56]]},{"type":"Polygon","id":3986,"properties":{"id":3986,"name":"Tujetsch"},"arcs":[[315,320,-325]]},{"type":"Polygon","id":3987,"properties":{"id":3987,"name":"Trun"},"arcs":[[-326,322,-327,311]]},{"type":"Polygon","id":3988,"properties":{"id":3988,"name":"Obersaxen Mundaun"},"arcs":[[313,62,57,323,325]]}]}},"arcs":[[[46625,65329],[-10,-217],[-120,-467],[-8,-178],[-128,-618],[-88,-224]],[[50963,67502],[-74,-72],[-56,-369],[-207,-235],[36,-312],[-330,-64],[-191,-619],[-59,-343],[-138,-334],[-743,453],[-410,692],[-30,316],[-84,167],[-227,-54],[-46,255],[-183,180],[-183,-118],[-197,5],[166,-502],[-38,-711],[-257,-79],[22,-260],[-417,17],[-311,-115],[-244,-4],[-137,-67]],[[51387,66219],[-96,106],[-61,377],[-80,114],[-53,388],[-134,298]],[[51143,64358],[0,364],[62,155],[15,372],[57,119],[-66,486],[176,365]],[[48225,58660],[313,659],[138,382],[90,542],[93,348],[-28,110],[157,473],[-38,341],[607,70],[536,199],[-25,506],[86,212],[142,694],[157,227],[187,380],[132,64],[252,423],[119,68]],[[46515,56586],[149,64],[266,-100],[531,670],[142,65],[-64,204],[-121,102],[167,116],[-11,88],[296,17],[49,255],[147,161],[-18,359],[177,73]],[[46079,58254],[330,-186],[139,18],[111,-106],[-139,-248],[-179,-549],[-38,-571],[212,-26]],[[45756,58706],[233,-222],[90,-230]],[[46271,63625],[32,-365],[310,-852],[-140,-698],[-201,-141],[-301,-377],[-578,-412],[81,-121],[331,56],[75,76],[249,-269],[2,-212],[-240,-294],[-199,-22],[-234,-325],[211,-150],[-25,-462],[149,-325],[-37,-26]],[[52044,63869],[-244,289],[-325,266],[-227,-109],[-105,43]],[[48225,58660],[86,-186],[118,-444],[258,-207],[127,-275],[279,-346],[186,3],[181,-182],[131,88],[-4,-408],[100,-144],[97,56],[109,-127],[206,228],[126,-16],[253,587],[204,366],[58,515],[95,434],[232,348],[105,685],[-124,460],[39,539],[166,84],[92,151],[254,238],[191,-44],[196,371],[-36,141],[18,384],[62,196],[-110,504],[6,366],[66,133],[52,711]],[[54781,63075],[-125,-232],[-16,-164],[-404,-356],[100,-538],[121,-368],[130,-653],[160,-270],[70,-456],[365,-322],[-7,-252],[55,-379],[-218,-695],[-128,-86],[86,-286],[140,-67],[165,-421],[144,-96]],[[55054,63090],[-273,-15]],[[56912,58596],[76,151],[-45,217],[-137,157],[-154,505],[23,326],[-29,452],[-57,287],[-155,177],[-241,628],[-506,684],[-269,249],[-84,207],[-241,308],[-39,146]],[[55419,57434],[129,264],[291,108],[326,292],[144,223],[412,94],[191,181]],[[45452,53691],[119,-241],[337,-249],[190,-229],[-13,-275],[80,-500],[-87,-426],[85,-328],[-114,-350]],[[46515,56586],[-34,-20],[169,-367],[133,-560],[4,-313],[-82,-262],[-430,-423],[-183,-326],[-207,38],[-433,-662]],[[54781,63075],[-130,251],[0,342],[343,344],[17,178],[143,173],[106,428],[193,34],[1,141],[141,168],[170,343],[167,162],[107,356],[45,334],[89,205],[-220,239],[-21,192],[-204,-291],[-212,75],[-48,-154],[-296,-146],[49,-179],[-197,-164],[-28,-249],[-234,657],[-115,-231],[-355,-385],[14,-189],[-157,-208],[-162,-100],[-92,-194],[6,-180],[-262,-147],[-172,-301],[-169,61],[-249,-179],[-317,-86],[-197,-274],[-108,11],[-383,-243]],[[54089,50470],[116,200],[-168,675],[56,374],[-26,571],[23,347],[85,236],[21,464],[-21,351],[44,521],[174,590],[-15,307],[53,160],[-123,368],[-319,438],[121,142],[286,118],[157,-25],[248,65],[115,100],[79,216],[300,283],[41,285],[83,178]],[[46049,51093],[741,803],[991,1390],[294,125],[865,-200],[366,-3],[241,-247],[349,13],[99,-102],[131,83],[153,-61],[81,-317],[202,71],[40,400],[-131,196],[928,113],[398,-224],[254,-583],[172,-278],[141,-83],[463,-638],[19,-154],[172,-141],[95,-210],[110,-26],[345,-363],[173,-112],[348,-75]],[[58575,43338],[-41,197],[48,232],[-29,350],[-127,252],[-115,80],[33,179],[-139,231],[-132,93],[-54,198],[48,295],[86,24],[-76,398],[-96,231],[19,125],[-243,178],[-355,447],[-52,377],[169,154],[-28,255],[46,223],[133,166],[-23,587],[-165,237],[-65,231],[-204,-136],[-296,25],[-414,-37],[-158,121],[-332,-57],[-206,88],[-216,12],[60,153],[-19,252],[-156,343],[-137,46],[-362,-108],[-118,-85],[-435,165],[-176,143],[-181,288],[22,179]],[[58743,38640],[-156,236],[-508,-29],[-114,106],[-265,-124],[-156,108],[-167,-24],[-288,407],[102,430],[-22,353],[-122,16],[-93,289],[38,212],[154,317],[34,273],[-171,139],[-82,456],[-127,452],[67,175],[137,-15],[187,163],[250,-76],[612,-59],[113,358],[166,176],[243,359]],[[58929,32288],[80,461],[107,356],[-206,157],[-139,247],[-65,978],[139,181],[1,714],[186,415],[-2,493],[-157,305],[-76,38],[34,236],[118,132],[-86,490],[-239,36],[-116,199],[99,532],[136,382]],[[56027,29084],[202,633],[177,102],[304,446],[170,104],[41,131],[356,180],[70,158],[225,241],[258,-37],[223,-133],[170,8],[362,298],[-34,347],[193,441],[62,8],[123,277]],[[52312,27544],[115,-356],[142,-81],[297,73],[192,-63],[465,15],[258,-141],[333,-13],[-61,111],[65,141],[221,-7],[127,214],[161,536],[230,122],[215,34],[381,-95],[42,471],[-32,334],[214,195],[350,50]],[[47460,36639],[28,-160],[197,-93],[212,-182],[460,0],[523,-102],[354,-277],[109,-243],[200,117],[78,-132],[31,-311],[98,-229],[12,-339],[186,-788],[273,-201],[42,-93],[300,-35],[315,-161],[198,18],[86,-124],[418,136],[113,-421],[289,-805],[184,-276],[126,-923],[-147,-531],[108,-523],[214,-431],[74,-850],[132,-545],[-236,-284],[-125,-307]],[[45919,46445],[45,-617],[104,-248],[107,-478],[155,-233],[-65,-155],[63,-123],[-13,-561],[167,-251],[133,-304],[-272,-113],[-161,-148],[73,-285],[-30,-298],[10,-610],[33,-316],[-32,-830],[-76,-506],[-241,-225],[109,-235],[70,-438],[387,-313],[288,-43],[311,96],[249,-21],[172,-222],[37,-298],[96,-143],[-14,-172],[129,-207],[145,-88],[108,-184],[72,-426],[-67,-79],[14,-231],[-239,-357],[-326,-144]],[[45995,48731],[-51,-125],[42,-639],[158,-285],[82,-297],[-109,-335],[-138,-159],[-97,-281],[37,-165]],[[46049,51093],[88,-107],[56,-429],[192,-391],[-28,-509],[-84,-223],[-84,-449],[-194,-254]],[[58575,43338],[489,361],[35,244],[177,171],[334,-71],[93,-144],[308,64],[57,120]],[[66625,58533],[-363,125],[-434,366],[-203,216],[-113,222],[-234,-170],[-50,-201],[-200,-46],[-103,-156],[-93,-304],[-147,-163],[-58,-224],[-161,-51],[-28,-108],[-304,-520],[-204,-130],[-195,246],[-219,410],[-221,251],[-427,-260],[-130,-179],[-200,-82],[-92,-139],[-282,-41],[-226,-286],[-295,-104],[-401,-347],[-371,-128],[-284,207],[-133,18],[-137,185],[-285,180],[-390,27],[-59,112],[32,352],[-230,573],[-175,312],[-11,705],[-34,137],[-437,-105],[-135,-307],[-32,140],[2,678],[-125,64],[-249,-169],[-110,40],[-277,-298],[-23,-242],[-194,-132],[60,-430],[277,-272],[210,-575],[-135,51],[-196,-62],[257,-458],[-305,-495],[-101,4],[-23,876],[-245,953],[-218,-267],[-128,127],[-126,-63]],[[67172,51720],[-669,2436],[-685,985],[37,325],[-40,148],[267,453],[64,328],[-110,224],[-52,343],[416,965],[225,606]],[[65860,49501],[93,505],[-108,270],[199,515],[48,294],[262,447],[75,-125],[194,-113],[448,308],[101,118]],[[64223,46017],[-286,686],[-147,1094],[223,285],[28,249],[-35,328],[336,56],[271,-149],[175,43],[223,267],[74,179],[150,54],[64,261],[162,130],[399,1]],[[60068,44083],[95,273],[333,-25],[172,175],[53,148],[630,106],[182,124],[194,-12],[249,253],[109,-22],[264,123],[208,-35],[20,106],[243,38],[544,217],[113,293],[494,154],[119,98],[133,-80]],[[77534,10653],[-189,-170],[5,-305],[-193,-320],[64,-343],[-34,-258],[-222,-348],[-279,-212],[-15,-151],[253,-111],[49,-147],[103,65],[212,-149],[41,-117],[155,-20],[257,-518],[173,-52],[43,-183],[217,-82],[538,946],[399,280],[323,97],[257,-90],[237,117],[319,-301],[535,-14],[242,-163],[286,214],[209,-14],[726,602],[244,1028],[1274,1723],[77,410],[-60,93],[-209,819],[-229,353],[-270,261],[9,263],[-123,229],[49,609],[-155,178],[-211,72],[-109,167],[137,339],[-139,382],[-94,141],[-285,59],[-478,511],[-57,169]],[[81616,16712],[-649,-489],[-312,-590],[-687,-41],[-72,-282],[356,-629],[-567,-1164],[-752,-1404],[26,-475],[-209,-127],[47,-333],[-90,-529],[-328,-159],[-296,-327],[-292,58],[-204,273],[-53,159]],[[76012,32160],[-36,-617],[84,-321],[-18,-146],[-157,-362],[-308,-173],[-271,113],[-268,199],[-110,-1260],[-11,-394],[-114,-266],[-637,-617],[-857,-749],[-242,-434],[-108,-77],[-105,-1158],[-225,-32],[-190,-265],[-30,-269],[-130,-371],[-103,-119],[-220,41],[-300,-76]],[[81616,16712],[38,393],[-291,142],[-103,169],[-165,94],[-52,147],[-231,218],[-183,50],[-213,168],[-13,164],[-135,315],[-11,286],[-249,748],[-238,397],[-73,223],[51,105],[-6,511],[63,189],[-46,148],[139,233],[31,244],[-88,464],[93,286],[188,-61],[303,530],[149,82],[115,181],[280,167],[2,238],[-90,345],[-95,574],[113,300],[-64,333],[91,210],[171,142],[156,276],[384,433],[270,91],[116,-146],[337,-55],[156,83],[276,578],[-71,361],[21,263],[-81,400],[-19,347],[38,224],[217,257],[-174,350],[-154,528],[-215,46],[-418,-361],[-97,151],[53,105],[-103,886],[-163,137],[-122,339],[-160,129],[-240,-20],[-132,56],[-95,250],[-97,11],[-116,-163],[-252,-14],[-164,-129],[-89,-355],[-88,-8],[-436,230],[-96,-331],[-176,-53],[-101,-404],[-190,-27],[-226,150],[-133,-5],[-196,-156],[-256,23],[-118,-67],[-60,223],[50,253],[-170,287],[-164,43],[-529,-317],[-162,166],[-153,284],[-87,674],[36,233],[-115,285],[-124,-148],[-179,165],[-196,85],[-200,-15],[-78,85]],[[71656,24807],[-155,-375],[-19,-150],[505,-1070],[362,-296],[169,-312],[178,-80],[290,-364],[114,-76],[41,-165],[225,86],[249,24],[142,-137],[-54,-129],[-32,-382],[95,-437],[-273,-339],[9,-216],[-297,-415],[22,-164],[-92,-303],[18,-144],[-221,-617],[329,-279],[53,-151],[270,-262],[177,-296],[161,23],[134,-86],[1,-337],[-195,-324],[133,-304],[126,-78],[3,-244],[-106,-59],[-114,-352],[-210,-81],[-52,-188],[56,-291],[95,-158],[49,-521],[61,-206],[251,-210],[323,-117],[161,-117],[71,45],[330,-161],[198,-18],[267,-136],[141,9],[489,-358],[325,-290],[81,-167],[118,-19],[293,-294],[149,2],[107,-128],[7,-343],[150,-500],[-78,-148],[125,-125],[6,-311],[115,-304],[2,-209]],[[27513,77945],[20,-273],[123,-517],[-12,-378],[-67,-166],[26,-435],[257,-676],[175,-146],[61,-219],[259,-491],[115,-523],[-7,-230],[110,-300],[-64,-573],[13,-236],[112,-369],[210,-463],[173,-239],[200,-101],[414,-337],[196,-280]],[[31848,69231],[110,187],[-60,78],[140,161],[-122,133],[20,384],[-74,82],[229,330],[-134,208],[66,371],[-120,233],[117,302],[122,67],[-251,220],[-123,-61],[-13,283],[-142,12],[-71,130],[-183,109],[-221,710],[-69,484],[19,574],[-200,31],[-345,296],[-193,44],[-509,324],[93,174],[-915,890],[-1506,1958]],[[29827,70993],[172,-193],[262,-477],[90,-76],[146,-339],[176,-239],[98,-338],[237,-76],[307,113],[533,-137]],[[34528,71843],[-390,19],[-210,129],[-398,390],[-122,181],[-354,666],[-353,785],[-252,295],[-203,415],[-146,509],[-204,499],[-300,549],[-8,189],[-189,317],[23,97],[-7,673],[-150,309],[-150,139],[-275,585],[-316,558],[-154,62],[-277,318],[-42,659]],[[31848,69231],[415,111],[292,317],[273,121],[-50,292],[262,286],[417,168],[361,214],[710,1103]],[[27044,78093],[469,-148]],[[30051,80186],[-101,-297],[-264,-292],[-101,-408],[-72,-2],[-151,-277],[-111,-7],[-341,-219],[-172,-261],[-341,230],[-246,48],[-1151,-4],[-172,44],[216,-648]],[[32744,68231],[58,196],[194,351],[171,77],[482,429],[186,355],[219,124],[131,-115],[335,26],[229,-187],[89,20],[133,304],[9,304],[-86,283],[77,396],[131,151],[93,-74],[122,105]],[[31915,68366],[255,-196],[260,-83],[314,144]],[[31848,69231],[-61,-153],[128,-712]],[[35317,70976],[-391,695],[-398,172]],[[29827,70993],[61,-417],[13,-614],[199,-461],[-10,-93],[166,-338],[0,-435],[-170,-195],[99,-113],[-24,-152],[-324,-327],[208,-282],[47,-161],[441,130],[373,-4],[217,198],[305,172],[177,402],[164,143],[146,-80]],[[21409,45698],[-209,-25],[-145,-134],[-93,-378],[11,-326],[-304,-493],[-80,-426],[-86,-173],[6,-462],[-181,-419],[80,-302],[-94,-348],[-182,-496],[129,-701],[-14,-202],[97,-191],[-69,-447],[-265,-210],[35,-333],[150,-45],[56,-167],[-9,-393],[143,-489],[-53,-134],[33,-302],[-32,-244],[125,-557],[230,-356],[39,-158],[149,-69],[166,-191],[138,-278],[100,-381],[70,-90]],[[31651,54121],[-86,253],[-54,643],[-214,796],[-526,451],[-47,84],[-309,-11],[-372,575],[-306,-434],[-191,-91],[-387,4],[-127,104],[-323,-11],[-99,54],[-54,-133],[38,-517],[73,-190],[-116,-290],[114,-111],[156,-351],[-800,-60],[-48,-78],[-384,143],[-140,-183],[-7,-374],[-195,-208],[15,-627],[50,-174],[-111,-261],[-161,-134],[-129,-213],[-225,-67],[-22,-199],[136,-166],[-36,-416],[152,-448],[-217,-715],[-378,-327],[-500,-233],[-224,-38],[-53,-214],[20,-213],[-127,-290],[-182,-285],[-105,-283],[-419,-463],[-47,-278],[-277,-423],[55,-381],[-6,-272],[-137,-10],[-72,-367],[-375,-462],[13,-70],[-157,-389],[-256,-398],[-175,-20],[-166,-172],[-235,-98],[-459,101],[-451,-136],[-122,223],[-157,155],[-48,304],[-250,-29]],[[31689,45085],[-75,183],[262,638],[-47,538],[26,282],[-211,880],[105,655],[-8,163],[138,440],[204,59],[92,104],[22,333],[-96,191],[-526,504],[-203,389],[178,68],[291,361],[103,783],[131,521],[-72,240],[-42,505],[-135,135],[-130,278],[-152,598],[107,188]],[[21350,35778],[-12,203],[108,555],[379,941],[376,181],[77,-14],[276,215],[151,-116],[106,25],[257,-86],[156,-136],[281,-64],[487,104],[98,-102],[242,-52],[382,115],[330,428],[163,496],[150,298],[123,8],[120,149],[38,186],[170,223],[503,381],[426,101],[175,97],[333,314],[245,94],[-36,196],[61,529],[439,511],[157,116],[744,334],[89,354],[415,208],[117,138],[394,31],[202,-53],[23,139],[162,216],[70,302],[99,100],[113,302],[338,126],[359,249],[243,26],[155,223],[55,716]],[[19843,55982],[-64,-211],[55,-314],[-30,-388],[-77,-198],[128,-493],[-23,-67],[184,-738],[196,-191],[66,-177],[-217,-600],[249,-572],[-53,-124],[-295,-360],[-273,-407],[-80,6],[-300,-292],[-175,-389],[-53,-293],[-264,48],[-69,300],[-376,8],[-839,221],[-86,-11],[-176,230]],[[28426,63856],[-504,-172],[-158,-148],[-163,-48],[-79,72],[-184,-123],[-37,-139],[-277,-184],[-113,-271],[-232,-24],[-245,-212],[-228,-322],[-57,-237],[-126,-170],[-399,-322],[6,-156],[-123,-262],[20,-131],[-170,-273],[51,-287],[-304,-153],[-65,-173],[-198,-236],[-158,-83],[-132,-210],[-148,-385],[-1,-498],[-138,-397],[-361,-620],[-270,-604],[-401,-162],[-501,81],[-973,-715],[-816,-408],[-246,-64],[-587,286],[-266,-124]],[[31651,54121],[270,671],[147,142],[99,827],[75,192],[74,557],[-76,408],[-103,283],[-209,345],[-196,460],[-137,73],[-91,170],[-61,297],[-134,120],[-191,512],[-206,300],[6,111],[-179,231],[-464,336],[-128,189],[-235,123],[-248,344],[-42,331],[188,136],[81,474],[167,136],[-4,224],[140,173],[160,329],[33,339],[114,250],[111,94],[-63,656],[-246,11],[-454,173],[-286,-340],[-155,-45],[-271,101],[-133,-108],[-578,110]],[[16637,50771],[25,-49],[299,-1293],[-169,-830],[149,-890],[241,127],[351,-108],[569,698],[626,341],[481,-31],[413,-362],[253,-519],[248,11],[245,-190],[109,-225],[374,78],[13,-690],[68,-202],[314,-191],[150,-319],[-80,-211],[93,-218]],[[17271,50970],[-64,-77],[-204,45],[-366,-167]],[[31651,54121],[365,64],[399,341],[179,275],[31,152],[164,135],[224,447],[172,208],[56,204],[169,242],[2,166],[128,170],[79,283],[174,826],[5,208],[115,282],[25,412],[123,243],[111,400],[133,264],[67,411],[-1,317],[-98,691],[-48,91],[9,325],[-40,429],[210,352],[198,133],[244,358],[-193,341],[-5,642],[-94,138],[-117,488],[-184,224],[-241,13],[-132,173],[-50,187],[-329,208],[-294,1044],[-114,524],[-50,602],[56,148],[-119,100],[-201,598],[-35,251]],[[25783,66374],[386,125],[269,-6],[201,246],[329,88],[98,-131],[100,65],[173,-107],[231,-42],[162,-204],[251,-63],[346,137],[161,-91],[-20,-178],[197,70],[397,-51],[-242,-160],[-670,141],[-100,-476],[-209,-656],[43,-263],[139,-147],[-18,-223],[180,-175],[239,-417]],[[22110,78045],[137,-463],[1,-178],[101,-298],[208,-442],[332,-563],[22,-211],[120,-394],[165,-77],[86,-349],[169,-206],[425,-671],[-383,-291],[329,-179],[198,-353],[366,-419],[38,-187],[167,-184],[120,-328],[-77,-240],[-50,-420],[124,-463],[21,-355],[253,-306],[48,-256],[239,-620],[23,-412],[127,-547],[-13,-255],[169,-284],[-9,-136],[165,-177],[119,105],[303,-38],[10,-123],[132,-10],[-214,-380],[-390,-269],[-61,-258],[153,-434]],[[27044,78093],[-243,-203],[-113,32],[-191,-151],[-111,-203],[-8,-231],[-125,-182],[-67,-430],[-240,-76],[-127,-150],[-290,-131],[-152,-375],[-291,-75],[-151,-200],[-167,-100],[-76,-179],[-174,14],[-246,176],[-79,798],[-385,710],[-112,150],[9,365],[-590,200],[-383,238],[-281,26],[-341,-71]],[[43298,60561],[95,1081],[19,594],[-38,70],[260,188],[-4,59]],[[43227,60650],[71,-89]],[[42970,61092],[257,-442]],[[42652,62282],[283,-1130],[35,-60]],[[43630,62553],[-282,-91],[-313,11],[-383,-191]],[[41119,69843],[-185,11],[-220,-96]],[[41626,66086],[607,184],[-107,104],[17,561],[145,243],[-222,95],[-112,220],[-17,180],[-144,207],[55,266],[-71,142],[70,132],[-61,288],[-413,274],[-159,262],[-33,296],[52,140],[-114,163]],[[41479,67040],[28,-503],[119,-451]],[[40714,69758],[26,-282],[688,-2071],[51,-365]],[[43298,60561],[242,-230],[201,-28],[216,-334],[37,-238],[92,52],[351,18],[45,-74],[-31,-345],[87,-200],[303,101],[156,-398],[119,-70],[269,81],[327,-71],[44,-119]],[[46271,63625],[-153,96],[-284,-128],[-52,49],[-449,-52],[-240,51],[19,-149],[-98,-260],[29,-90],[-200,69],[-494,-229],[73,-196],[-497,-96],[-295,-137]],[[43227,60650],[-179,-1369],[-202,-670]],[[44710,56051],[87,-35],[-194,358],[-222,233],[-221,79],[-110,334],[130,41],[-63,179],[142,12],[82,251],[360,57],[90,-74],[67,148],[524,395],[593,157],[104,68]],[[42846,58611],[-11,-292],[130,-104],[141,-283],[24,-197],[132,-272],[124,-92],[108,-281],[9,-189],[-189,-229],[80,-341],[315,-103],[401,-31],[600,-146]],[[38153,59801],[740,440],[210,-164],[128,193],[187,69],[150,-147],[244,-28],[101,-166],[256,102],[186,158],[277,-194],[279,23],[438,-70]],[[39338,66093],[-81,-61],[88,-346],[-70,-558],[-103,-153],[191,-498],[-140,-255],[-2,-219],[-452,-1050],[-98,-378],[-81,-21],[-205,-410],[15,-92],[-221,-473],[-32,-548],[96,-229],[62,-785],[-152,-216]],[[41479,67040],[-591,-35],[-18,111],[-596,-54],[191,-266],[-459,-486],[-495,-242],[-173,25]],[[42652,62282],[-549,2110],[-477,1694]],[[42389,59772],[206,147],[-382,704],[239,85],[518,384]],[[41349,60017],[18,225],[98,204],[71,356],[446,-78],[164,-121],[22,-226],[207,-283],[14,-322]],[[38153,59801],[221,-337],[459,-136],[257,-204],[359,-116]],[[41344,58646],[175,1099],[-170,272]],[[39449,59008],[-46,488],[538,-71],[-33,-191],[405,-126],[1031,-462]],[[40304,54593],[235,443],[176,-34]],[[40502,57195],[-361,-189],[-122,-132],[123,-193],[7,-387],[-111,-183],[25,-421],[161,-373],[88,-554],[-8,-170]],[[40715,55002],[52,131],[39,540],[-27,206],[-213,523],[20,365],[-53,60],[-31,368]],[[41344,58646],[-29,-210],[152,-165],[-371,-638],[-49,-329],[64,-438]],[[41111,56866],[141,283],[264,168],[223,66],[38,-106],[140,104],[-68,115],[137,30],[44,353],[110,219],[-199,237],[332,390],[174,599],[-58,448]],[[44710,56051],[122,-416],[22,-445],[394,-827],[52,-432],[152,-240]],[[43477,57022],[-94,329],[-249,320],[-27,243],[-152,290],[-130,107],[21,300]],[[41987,55772],[-5,435],[83,207],[262,297],[208,146],[198,252],[150,61],[358,-19],[236,-129]],[[41187,55358],[343,294],[2,265],[455,-145]],[[41111,56866],[-35,-403],[165,-555],[-54,-550]],[[40502,57195],[-216,520],[68,155],[-169,219],[-81,556],[-201,286],[-109,-104],[-221,165],[-124,16]],[[37537,52374],[181,422],[228,305],[111,420],[265,327],[19,179],[239,235],[119,26],[333,-169],[89,93],[147,-63],[177,201],[241,-39],[44,104],[331,50],[243,128]],[[38153,59801],[-373,-363],[-294,-173],[-27,-137],[-442,-401],[-257,-738],[-74,-303],[-107,-125],[-46,-199],[-284,-550],[-150,-148],[371,-363],[218,58],[102,-161],[195,-124],[116,-239],[259,-382],[128,-419],[-8,-370],[-90,-339],[67,-312],[-93,-135],[29,-213],[-38,-380],[-194,-138],[-55,-317],[43,-187],[129,-140],[105,95],[154,-224]],[[40715,55002],[325,223],[41,216],[106,-83]],[[36031,47939],[-47,117],[-24,541],[18,602],[-275,232],[-168,83],[-164,228],[16,226],[209,408],[-82,177],[-31,345],[125,504],[277,-35],[431,308],[281,138],[371,28],[138,227],[207,171],[194,32],[30,103]],[[35705,46540],[115,391],[-38,249],[67,166],[-23,192],[94,323],[111,78]],[[31689,45085],[132,-9],[279,229],[140,-198],[389,102],[87,79],[392,158],[433,84],[259,113],[261,308],[166,90],[176,-23],[217,70],[132,136],[211,-21],[210,154],[249,28],[283,155]],[[36029,71194],[-2,-271],[-226,-57],[-45,161],[-176,115],[-165,-35],[-98,-131]],[[36570,70733],[-189,-105],[-79,42],[-146,435],[-127,89]],[[38708,67923],[18,505],[-152,120],[-200,34],[-173,-146],[-208,-22],[-109,-229],[-116,-95],[-147,548],[-209,277],[36,170],[-123,364],[-176,214],[-27,188],[164,294],[-143,113],[-31,195],[-307,-25],[-235,305]],[[39338,66093],[2,97],[-173,137],[118,237],[-151,296],[-32,240],[-127,-110],[-279,323],[12,610]],[[45599,70621],[-296,-199],[-704,-209],[-211,38],[-234,224],[-325,496],[-174,522],[-103,8],[-91,272],[-369,-171],[0,-127],[-451,-520],[-424,-289],[-206,288],[-268,-161],[-86,-208],[-130,-51],[-369,-447],[-39,-244]],[[46625,65329],[-121,336],[-81,395],[-241,571],[-341,157],[-138,131],[10,103],[-118,377],[-272,536],[104,310],[203,105],[229,242],[-376,1633],[116,396]],[[44158,27860],[510,304],[106,444],[270,167],[267,520],[229,366],[179,-377],[28,267],[87,98],[619,505],[225,19],[146,130],[347,-486],[313,-125],[-23,-393],[61,-82],[83,-439],[63,-93],[44,-374],[85,-240],[41,-448],[-106,-469],[177,-700],[103,-77],[111,-264],[-91,-222],[17,-206],[372,-652],[361,-307],[144,-43],[516,-404],[499,681],[135,272],[39,213],[110,70],[84,374],[-47,416],[42,219],[278,256],[300,41],[123,72],[190,-201],[107,-11],[264,547],[63,335],[233,173],[450,-192]],[[44349,35031],[98,-209],[-12,-355],[120,-646],[-41,-319],[-295,-404],[43,-163],[-60,-490],[34,-379],[70,-277],[-37,-543],[74,-438],[-184,-660],[57,-308],[-89,-483],[-68,-1162],[99,-335]],[[44276,35513],[73,-482]],[[44409,38075],[-173,-274],[65,-343],[41,-581],[-45,-370],[26,-407],[-56,-360],[9,-227]],[[47460,36639],[-210,-186],[-247,97],[-62,107],[-92,-96],[-137,78],[-211,252],[-143,-64],[-385,52],[-131,227],[-240,5],[-80,344],[-433,414],[-157,-60],[-143,114],[-380,152]],[[35705,46540],[150,-199],[249,-35],[96,-76],[7,-523],[88,-57],[157,-497],[521,-20],[350,254],[269,-159],[91,-141],[300,-265],[170,-503],[126,-118],[255,-400],[131,-313],[57,-394],[126,-372],[504,-565],[17,-347],[-249,-415],[43,-347],[-128,-143],[-36,-255],[97,-109],[-38,-384],[-236,-134],[-22,-179],[-194,-432],[118,-50],[137,-252],[92,-340],[-59,-308],[19,-240],[-55,-165]],[[37141,47468],[-224,72],[-156,188],[-730,211]],[[41051,41701],[3,141],[178,390],[126,168],[106,518],[-160,261],[24,418],[-56,549],[44,153],[0,360],[-373,239],[-68,325],[-251,242],[-389,448],[-371,217],[-429,415],[-354,187],[-229,48],[-226,119],[-1485,569]],[[39466,37461],[326,229],[215,223],[40,167],[367,395],[128,7],[242,638],[-9,417],[93,280],[4,349],[62,398],[182,659],[-65,478]],[[38858,38057],[108,-41],[224,-432],[276,-123]],[[42563,50850],[-149,-321],[-180,232],[-86,-175],[-141,-36],[-26,-166],[-192,-100],[-93,-333],[-148,33],[-2,-160],[-169,177],[-222,-51],[-476,-314],[-290,-456],[-293,-206],[-31,-239],[-202,-146],[-302,-663],[-163,-33],[-136,83],[-186,-178],[-267,47],[-202,-139],[-212,-10],[-403,109],[-245,0],[-279,115],[-327,-452]],[[45995,48731],[-287,286],[-341,100],[-308,463],[-151,441],[-81,16],[-143,246],[-127,86],[-339,-72],[-1449,368],[-206,185]],[[41051,41701],[227,379],[297,331],[386,114],[91,363],[203,126],[265,684],[111,534],[82,161],[-80,456],[93,143],[138,35],[-56,293],[217,219],[112,205],[161,145],[47,-375],[178,-127],[261,-3],[70,238],[115,160],[221,148],[445,54],[499,-236],[150,128],[233,-76],[53,139],[313,396],[36,110]],[[41987,55772],[385,100],[171,87],[352,70],[192,-116],[188,-376]],[[43275,55537],[105,391],[-77,694],[151,175],[23,225]],[[43275,55537],[-160,-305],[-183,49],[241,-831],[-159,-414],[95,-415],[-5,-389],[-59,-181],[-316,-348],[-78,-252],[-244,-577],[254,-40],[-32,-676],[57,-29],[-123,-279]],[[39466,37461],[17,-434],[-204,-267],[-59,-400],[151,-502],[171,-76],[125,-453],[75,-89],[132,59],[111,-187],[170,-18],[13,-195],[150,-177],[-4,-263],[144,-361],[209,-89],[190,-297],[71,27],[284,-126],[284,-197],[223,44],[240,592],[325,423],[15,483],[-28,177],[111,409],[-92,331],[148,318],[130,128],[221,588],[1121,862],[80,240],[103,103],[271,68],[45,-107]],[[44276,35513],[-649,-75],[42,-486],[680,79]],[[34584,36527],[389,36],[98,124],[253,82],[229,201],[203,34],[317,360],[129,-19],[237,96],[1049,180],[89,-50],[24,-190],[181,17],[318,174],[160,12],[208,-122],[152,169],[26,186],[212,240]],[[23469,34080],[4173,3169],[1383,86],[918,88],[307,-152],[-3,146],[155,-221],[182,53],[246,277],[202,124],[511,449],[-4,161],[119,293],[1036,85],[770,390],[279,355],[122,27],[211,-456],[-98,-145],[-8,-677],[104,-99],[479,-194],[-53,-675],[1,-298],[83,-339]],[[21350,35778],[-60,-266],[73,-221],[264,-148],[160,-495],[-134,-258],[165,-164],[148,-53],[181,-278],[342,-41],[252,228],[450,232],[278,-234]],[[41022,71148],[175,320],[-42,301],[-294,81],[-159,222],[-10,219],[75,396],[-72,275]],[[38708,67923],[449,65],[-51,104],[68,206],[207,110],[-80,350],[-229,213],[-132,554],[-87,-86],[-24,1132],[-132,273],[142,373],[295,-34],[257,57],[287,-104],[1229,-15],[115,27]],[[38961,72935],[-281,-121],[-338,-431],[-81,-288],[-243,-89],[-154,123],[-165,-82],[-357,-556],[-230,-511],[-250,0],[-292,-247]],[[40695,72962],[-97,194],[-235,-52],[-517,-273],[-302,27],[-288,-48],[-158,-145],[-137,270]],[[42431,74747],[-221,-239],[-48,-208],[-123,-185],[-254,-44],[-506,-364],[-142,-56],[-160,-536],[-202,-166],[-80,13]],[[44836,75484],[-347,-172],[-231,-52],[-261,-149],[-570,-439],[-629,-11],[-367,86]],[[45558,72563],[-218,45],[-152,131],[-6,184],[-122,98],[62,591],[-91,466],[9,166],[111,10],[56,191],[-60,364],[-166,475],[-145,200]],[[45599,70621],[-111,388],[55,210],[-304,587],[19,225],[185,74],[115,458]],[[41022,71148],[-186,-692],[-156,-276],[34,-422]],[[42830,78505],[-227,-280],[-141,-76],[234,-498],[253,-460],[279,-429],[-237,-200],[-204,-26],[-241,88],[-61,170],[-142,-44],[-59,-129],[-235,-131],[22,-267],[-89,-99],[-166,43],[60,-461],[68,-245],[125,77],[362,-791]],[[43110,79797],[68,-159],[11,-303],[-164,-631],[-195,-199]],[[44836,75484],[199,284],[302,699],[-238,786],[-41,264],[-131,291],[-314,-366],[-229,322],[-128,355],[-331,700],[-89,309],[-229,313],[-497,356]],[[32929,81541],[-506,545],[-179,531],[-300,327],[-215,-204],[-167,-394],[-100,-345],[-278,34],[-193,-185],[-232,-128],[-102,-453],[-344,-721],[-262,-362]],[[36029,71194],[-83,613],[30,1628],[82,446],[79,186],[551,308],[264,-5],[123,164],[-33,344],[-227,615],[-265,242],[14,238],[-104,308],[-117,141],[-120,-9],[-153,-164],[-101,18],[-171,320],[-29,175],[-317,317],[-99,500],[-163,566],[-294,445],[-53,149],[-145,-52],[-238,24],[-1150,486],[-795,145],[-22,467],[96,77],[35,695],[169,527],[117,93],[19,340]],[[42830,78505],[-456,636],[-155,102],[-256,527],[-275,98],[-160,229],[-297,201],[-217,50],[-112,117],[-213,81],[-506,23],[-342,106],[-385,342],[-304,102],[-380,-51],[-360,36],[-133,-94],[-232,38],[-772,233],[-208,-161]],[[37067,81120],[-58,-1482],[679,-196],[189,-497],[543,-774],[0,-910],[210,-953],[295,-315],[149,-241],[43,-361],[268,-702],[-20,-233],[219,-654],[-204,-159],[104,-456],[-269,153],[-217,-36],[-37,-369]],[[37067,81120],[-248,407],[-223,-3],[-472,-115],[-49,-90],[-391,81],[-273,378],[-151,110],[-347,1],[-132,-48],[-422,164],[-138,-18],[-203,-218],[-353,229],[-344,-66],[-392,-391]],[[87474,59511],[-104,38],[-274,-52],[-323,231],[-172,-4],[-291,168],[-243,199],[-542,23],[-351,275],[-333,177],[-75,150],[-218,1],[-243,-96],[-199,161],[-176,-15],[-240,81],[-145,176],[-62,350],[-249,594],[-230,27],[-276,682],[-349,-92],[-542,325],[-468,630],[-391,105],[0,326],[-248,290],[-60,225],[61,537],[253,256],[68,487],[-53,260],[43,439],[-360,563],[-147,365],[-319,631],[226,90],[-3,268],[86,122],[-72,127],[94,59],[51,415],[-56,261],[51,245],[-113,72],[-66,206],[28,559],[-66,192],[-8,450],[-663,168],[-478,75],[-137,624],[-140,190],[1,210],[149,366],[43,526],[-419,182],[-58,106],[161,497],[-24,185],[-132,173],[-106,376],[54,169],[-118,232],[-207,78],[-31,704],[-52,113],[168,384]],[[86544,52578],[271,261],[17,212],[-75,394],[-326,941],[-292,221],[80,273],[634,187],[305,-127],[462,572],[489,722],[215,527],[-246,215],[-41,402],[-117,123],[-35,189],[-241,240],[-204,889],[47,302],[-13,390]],[[78843,50932],[235,6],[140,-204],[227,-173],[360,-125],[217,40],[209,-102],[253,144],[117,187],[113,-2],[13,274],[101,83],[256,-23],[221,202],[189,247],[389,74],[92,126],[116,-46],[608,511],[490,460],[263,192],[258,52],[42,-309],[711,-227],[496,-400],[242,536],[-26,255],[229,584],[182,101],[86,191],[320,222],[184,206],[85,-19],[15,-410],[59,-476],[209,-531]],[[70658,59742],[-5,-141],[262,-268],[153,-299],[10,-230],[-97,-113],[-28,-425],[297,-328],[447,-353],[237,-72],[62,-140],[273,-131],[113,-152],[576,-505],[476,-646],[217,-208],[241,-111],[235,-237],[290,-160],[382,-123],[513,-462],[313,-337],[91,-24],[969,-988],[-153,-397],[57,-204],[-52,-357],[288,79],[58,-55],[316,43],[248,196],[430,-81],[204,-157],[297,-4],[103,-392],[-33,-350],[144,-344],[251,-334]],[[71110,67447],[-138,-218],[131,-460],[-142,-227],[-202,-75],[-381,-381],[-118,-35],[-93,164],[-200,-26],[-667,-291],[202,-409],[7,-272],[315,-855],[-8,-182],[94,-161],[68,-304],[-115,-427],[144,-236],[85,55],[45,-256],[166,30],[194,-73],[263,-420],[64,-212],[-23,-260],[-78,-196],[-113,-56],[30,-354],[-165,-222],[75,-392],[184,-364],[-4,-498],[-72,-92]],[[77913,77301],[-395,-332],[-141,-311],[-89,-56],[-36,-322],[-118,-133],[26,-257],[-143,-218],[-177,150],[-211,-107],[-61,-349],[-116,-235],[146,-64],[170,-209],[-113,-106],[-140,-285],[-199,-245],[-206,-791],[18,-176],[-433,-29],[-348,-160],[-206,-274],[-314,100],[-208,-36],[-161,96],[-163,-1157],[-368,-637],[-178,-61],[-934,-147],[-101,-282],[-237,-261],[-24,-296],[-198,-386],[-50,-439],[-25,-693],[-531,-509],[-142,-71],[-130,-235],[-116,-71],[-151,-260]],[[78379,76448],[-180,440],[-286,413]],[[95818,90147],[-248,-57],[-197,174],[-218,276],[38,171],[-9,418],[165,392],[56,403],[-23,261],[-205,360],[-282,283],[-317,159],[-114,170],[-220,477],[-255,241],[-227,686],[-495,349],[-247,-72],[-229,-342],[-95,-246],[-255,-266],[-56,-185],[-217,-28],[-139,77],[-324,-3],[-230,61],[-351,-203],[-132,-126],[-1,-408],[-85,-360],[-241,-168],[47,-323],[-46,-157],[-271,-509],[-15,-339],[-146,-292],[-86,-298],[25,-589],[-85,-556],[-114,-155],[-255,-145],[-92,30],[-289,-77],[-235,-123],[-79,-351],[57,-400],[-121,-372],[220,-468],[151,-145],[249,-375],[4,-557],[-47,-86]],[[89537,86354],[216,-212],[224,-58],[521,-514],[10,-223],[135,-131],[54,-341],[235,-118],[88,-300],[-5,-315],[64,-107],[568,-119],[171,85],[122,-60],[326,-6],[129,-256],[339,-199],[254,337],[9,904],[-117,299],[-19,200],[67,162],[13,447],[120,325],[-18,559],[65,469],[151,297],[28,442],[218,373],[109,391],[327,400],[141,60],[241,291],[20,95],[231,137],[180,181],[305,-101],[287,23],[337,135],[135,241]],[[86363,86702],[-34,-625],[71,-980],[84,-484],[133,-87],[5,-220],[98,-174],[18,-495],[-176,-71],[-80,-443],[63,-345],[95,-195],[11,-422],[-371,-176],[-92,44],[-128,-157],[31,-217],[178,-315],[-450,-1167],[-164,-43],[-478,57]],[[88331,85924],[-1459,699],[-509,79]],[[95704,71483],[-118,202],[-6,159],[-168,178],[-127,308],[-132,50],[-72,225],[75,261],[-51,316],[-102,-12],[-252,429],[-50,208],[-199,142],[-161,243],[-91,414],[-347,435],[-130,90],[-456,43],[146,243],[-166,287],[-79,16],[-193,-349],[-126,-115],[-235,91],[-73,140],[72,424],[137,265],[-20,131],[-316,186],[-11,129],[-163,28],[-67,195],[-211,30],[-125,106],[-197,37],[-189,188],[-79,-32],[-243,451],[-113,305],[-311,650],[-46,632],[32,123],[-95,136],[-130,435],[19,307],[78,110],[-16,212],[-90,88],[-20,236],[-124,276],[-1,295],[-179,553],[-177,122],[-134,321],[-142,116],[-87,202],[-205,149],[-232,621],[-364,351],[-225,142],[-229,47],[-170,334],[-142,170],[-9,465],[-75,196],[43,228],[99,49],[197,428]],[[94551,56595],[-111,47],[-70,427],[82,172],[-37,612],[-77,226],[77,391],[-149,338],[-17,189],[-97,122],[-135,444],[-219,323],[86,296],[243,15],[280,227],[164,560],[-16,109],[346,1165],[226,-46],[193,110],[161,193],[56,207],[-6,316],[140,261],[-32,305],[50,223],[-184,78],[-339,590],[4,208],[-96,184],[-211,142],[-220,260],[61,158],[277,190],[97,172],[192,166],[45,221],[537,526],[649,849],[181,36],[162,-59],[81,499],[9,631],[-101,309],[-54,409],[9,251],[-136,428],[-286,333],[-31,364],[-146,109],[-123,280],[-316,175],[-46,147]],[[87474,59511],[31,147],[394,291],[183,296],[208,-317],[129,-348],[405,-85],[22,-137],[151,-225],[211,-139],[75,-141],[216,-20],[320,-262],[275,-63],[0,-238],[72,-335],[-41,-85],[45,-488],[94,-180],[483,-355],[454,-672],[100,58],[199,-110],[301,52],[155,-92],[267,31],[295,-151],[315,9],[515,72],[180,64],[392,35],[105,-79],[171,36],[196,221],[159,294]],[[85177,80187],[-83,-244],[107,-344],[-543,-17],[-224,81],[-497,-291],[-120,39],[-169,-76],[-266,211],[-289,-35],[-123,-390],[-292,-271],[-113,-190],[-72,-373],[-185,-191],[-363,-60],[-71,-265],[-86,-81],[-258,36],[-115,-56],[-230,-315],[-83,-2],[-55,253],[-430,115],[-354,-446],[-474,-44],[-436,62],[-192,-89],[-30,-352],[-258,-108],[-71,-135],[-423,-161]],[[89537,86354],[-355,53],[-346,-89],[-140,-82],[-180,-515],[-185,203]],[[95704,71483],[205,181],[68,165],[-74,329],[145,122],[0,168],[508,123],[195,159],[134,189],[122,21],[166,409],[169,671],[1,231],[105,173],[69,308],[-102,192],[-15,409],[234,282],[-224,614],[126,160],[49,355],[163,-64],[180,207],[-13,388],[-147,195],[137,306],[114,437],[157,112],[-136,682],[-111,793],[110,516],[33,695],[-95,462],[-40,435],[-133,254],[-121,84],[227,573],[158,215],[-8,105],[154,247],[21,341],[-33,439],[124,229],[42,472],[-11,358],[246,202],[147,338],[-61,348],[79,206],[-29,172],[90,479],[-19,193],[-142,191],[13,357],[108,153],[-41,179],[102,205],[-71,103],[-248,18],[-128,109],[-279,100],[-166,192],[-83,241],[-154,201],[-249,91],[-180,180],[-233,120],[-118,221],[-303,-84],[-370,188],[-213,39],[-63,137],[-174,43]],[[86363,86702],[-274,91],[-584,71],[-43,-654],[43,-525],[62,-179],[-78,-249],[-191,-170],[-54,-260],[43,-130],[-68,-287],[-32,-620],[-51,-272],[-148,-377],[-235,-199],[78,-264],[-31,-128],[97,-378],[133,-61],[237,-468],[-41,-183],[36,-228],[-25,-350],[-73,-201],[13,-494]],[[60406,39442],[-53,135],[-14,512],[162,548],[142,279],[-15,188],[222,182],[101,189],[-66,385],[21,267],[-47,845],[-266,49],[-330,456],[-32,250],[-163,356]],[[59924,38322],[251,350],[64,314],[-16,165],[183,291]],[[58743,38640],[72,-99],[517,-180],[152,37],[292,-90],[148,14]],[[64223,46017],[-168,-798],[-18,-274],[-138,-222],[-423,-844],[-88,-306],[-333,-304],[-36,-395],[123,-145],[471,22],[235,-176],[235,55],[590,44],[87,-40],[192,169],[27,174],[291,375],[215,110],[213,5],[397,-221],[198,-27],[465,218],[216,146],[293,-169],[-224,-313],[71,-142],[170,335],[29,279],[295,-102],[399,-3],[64,-199],[-233,-247],[218,-294],[579,-401],[449,-160],[188,-206],[151,-36],[274,-310],[92,-33]],[[69789,41582],[99,403],[-211,437],[-167,226],[-219,580],[-207,181],[-53,412],[-236,163],[-290,342],[116,402],[-134,172],[147,472],[-176,6],[-147,121],[-478,700],[-210,255],[-387,-190],[-324,-362],[-151,-17],[-200,133],[-177,-94],[-300,66],[-332,139],[-415,-78],[-58,-58],[-188,95],[-176,-10],[-163,83],[-182,-17],[-347,-127]],[[66202,34759],[126,100],[161,-16],[59,145]],[[61832,38869],[163,-290],[163,64],[193,-20],[290,135],[328,218],[149,40],[424,-36],[248,31],[161,86],[149,-48],[91,129],[290,177],[280,-636],[127,-209],[348,-46],[242,-191],[268,-87],[168,-152],[234,-734],[-159,-450],[235,-822],[41,-807],[-68,-184],[5,-278]],[[67134,39008],[-159,113],[-310,747],[-321,420],[-125,316],[0,272],[-137,-233],[-3,164],[-185,-147],[-558,157],[-203,198],[-196,291],[-349,300],[-146,-131],[-137,3],[-179,155],[-407,-240],[-201,82],[-53,170],[-112,33],[-131,237],[-175,-261],[-117,-70],[-171,-251],[-192,45],[-201,-88],[53,-132],[-283,-313],[-239,-59],[-45,-269],[150,-264],[-58,-272],[-101,-158],[142,-240],[-161,-365],[8,-349]],[[66548,34988],[92,194],[725,1055],[235,-60],[113,218],[75,282],[-30,294],[191,305],[172,150],[-151,394],[-216,258],[-118,65],[-209,255],[-150,441],[-143,169]],[[71535,45997],[13,572],[-213,673],[-231,397],[-170,154],[-250,-258],[-304,515],[96,233],[-305,143],[-246,287],[-188,-7],[-60,-111],[-156,95],[-199,-80],[-220,384],[-111,1211],[-81,417],[-243,252],[-151,227],[-125,309],[-59,338]],[[67828,48815],[507,-819],[314,-51],[339,-1],[256,-134],[300,-561],[234,129],[43,-209],[240,105],[229,-319],[-178,-483],[428,-253],[142,-273],[171,-139],[286,-18],[255,245],[141,-37]],[[67874,52318],[-44,-414],[226,-642],[167,-348],[22,-206],[247,-673],[43,-338],[104,-352],[23,-262],[-295,-446],[-121,-125],[-418,303]],[[68332,51748],[-244,390],[-214,180]],[[72939,39159],[18,-170],[-154,-703],[78,-333],[106,-208],[-155,-600],[82,-195],[-52,-296],[76,-160],[-228,-473],[4,-123]],[[74159,36173],[-51,299],[110,348],[31,407],[-160,171],[-66,304],[85,248],[-117,433],[71,471],[-72,514],[903,824],[-30,149],[-246,463],[-91,311],[-893,-708],[135,-337],[-350,-384],[-141,-293],[-338,-234]],[[72714,35898],[234,263],[101,-128],[207,37],[345,-334],[46,-111],[260,280],[92,-36],[182,121],[-22,183]],[[76069,35936],[-189,-115],[-273,-52],[-55,112],[-377,-10],[-323,220],[-321,-89],[-372,171]],[[76012,32160],[-171,466],[174,227],[-42,357],[109,321],[163,113],[-27,162],[313,337],[96,477],[-119,131],[-50,216],[-14,482],[-245,395],[-130,92]],[[68827,24968],[131,-138],[90,-266],[237,-399],[88,-342],[221,129],[115,-91],[126,-500],[218,95],[100,143],[-66,408],[115,226],[326,283],[288,178],[110,-9],[383,221],[281,-29],[66,-70]],[[66548,34988],[892,43],[-6,-30],[758,-422],[141,-765],[55,-101],[28,-491],[153,-442],[-54,-166],[-42,-446],[-25,-728],[17,-163],[-118,4],[-113,-219],[72,-240],[-129,-167],[-22,-317],[-156,-330],[36,-353],[187,-357],[209,-191],[21,-333],[-62,-176],[61,-117],[26,-446],[-74,-246],[62,-264],[204,-454],[37,-352],[98,-17],[-83,-664],[33,-78],[-1,-517],[114,-285],[-40,-190]],[[70521,37760],[-149,4],[-471,474],[-130,14],[-257,179],[-305,115],[-115,235],[-232,91],[-106,236],[-560,172],[-388,-124],[-22,342],[-652,-490]],[[72714,35898],[-235,10],[-112,-232],[-185,-35],[-114,125],[-248,40],[-355,723],[-126,56],[-146,299],[42,127],[-94,131],[-311,119],[-222,436],[-87,63]],[[69789,41582],[81,-201],[210,-105],[104,-155],[360,-259],[219,-345],[112,-265],[26,-276],[115,-143],[-125,-656],[-153,-435],[-196,-250],[32,-483],[-53,-249]],[[67828,48815],[-258,99],[-198,255],[-342,107],[-498,-57],[-616,320],[-56,-38]],[[72939,39159],[-141,165],[14,325],[186,875],[-246,305],[232,543],[106,132],[-125,569],[47,443],[100,476],[-35,317],[25,328],[-134,95],[105,303],[-189,239],[36,382],[-172,10],[-85,122],[51,145],[-46,403],[-318,261],[-58,123],[-248,151],[-227,24],[-144,131],[-138,-29]],[[63983,28281],[-199,-484],[134,-370],[-66,-141],[-7,-298],[97,-211],[-45,-303],[-122,-287],[-50,-268],[54,-210],[25,-648],[91,-404],[146,-455],[-79,-258],[-95,-58],[-31,-270],[157,-217],[145,25],[278,-166],[200,-279],[149,-439]],[[65411,33343],[-30,-417],[-232,-93],[118,-331],[-15,-275],[82,-181],[-72,-280],[-113,-36],[-89,-420],[26,-381],[-102,-79],[92,-386],[-50,-315],[-163,-292],[-860,-1050],[-20,-526]],[[66202,34759],[-102,-254],[4,-255],[-191,-52],[-203,-575],[-35,-185],[-264,-95]],[[64765,22540],[302,60],[142,172],[98,-106],[221,49],[143,262],[131,28],[153,-138],[169,116],[160,-66],[70,122],[235,28],[148,-244],[154,120],[418,514],[88,59],[151,368],[38,227],[110,-47],[545,426],[200,74],[37,145],[349,259]],[[60406,39442],[238,-316],[328,-269],[359,45],[90,-349],[411,316]],[[59924,38322],[399,-822],[153,-56],[79,-202],[-93,-239],[67,-174],[108,-46],[309,28],[140,-60],[127,-245],[24,-317],[121,-294],[244,41],[209,160],[1110,358],[253,-501],[117,-132],[56,-300],[318,-230],[201,-356],[542,-594],[729,-855],[173,-9],[101,-134]],[[67172,51720],[32,233],[219,439],[289,74],[162,-148]],[[70658,59742],[-201,38],[-510,-82],[-286,276],[-146,14],[-405,-108],[-55,-154],[-357,-198],[-149,-5],[-230,-271],[-28,-282],[-113,-223],[-161,5],[-369,-199],[-234,-275],[-219,51],[-342,-171],[-132,324],[-96,51]],[[76000,43398],[188,9],[62,102],[342,-5],[200,115],[158,412],[179,108],[80,241],[-33,194],[102,244],[-9,184],[141,252],[236,66],[125,250],[120,109],[148,375],[-142,278],[-176,172],[-69,420],[216,25],[703,266],[73,338],[183,270],[39,264],[-85,192],[41,305],[-180,270],[-41,152],[21,477],[124,151],[66,218],[-145,414],[91,238],[85,428]],[[68332,51748],[87,124],[229,77],[112,-125],[447,-170],[106,-106],[342,194],[127,-41],[295,596],[1156,-573],[297,-272],[47,-206],[-105,-397],[44,-182],[214,-462],[229,-362],[35,112],[200,-69],[285,161],[175,154],[147,-57],[170,-179],[644,-978],[119,-220],[40,-381],[-46,-131],[34,-347],[-106,-149],[-37,-512],[114,-460],[-31,-258],[-205,-251],[-2,-272],[-107,-399],[-283,-339],[-117,-225],[206,-216],[352,-179],[257,67],[214,-394],[320,-77],[152,75],[233,-230],[352,4],[291,-164],[134,99],[183,-59],[176,-277],[143,-95],[-1,-199]],[[62235,20238],[154,-8],[156,189],[369,178],[270,24],[215,355],[112,42],[364,330],[171,-49],[377,533],[173,194],[158,358],[11,156]],[[56027,29084],[235,-101],[337,-474],[541,202],[372,-495],[259,100],[42,222],[608,59],[183,117],[358,94],[1114,55],[69,-180],[26,-452],[160,-322],[100,-651],[381,-942],[-15,-189],[95,-301],[63,-434],[102,-272],[44,-297],[11,-447],[58,-236],[25,-579],[130,-321],[-15,-241],[135,-429],[89,-149],[62,-416],[-33,-349],[44,-126],[155,-73],[207,-317],[224,-642],[42,-260]],[[63983,28281],[-769,514],[85,285],[-371,576],[-54,426],[264,174],[-106,134],[-287,514],[-149,516],[-9,323],[-693,340],[-149,120],[-1097,1023],[-48,-60],[-381,306],[-159,-363],[-38,-205],[-452,-316],[-305,-257],[-115,-213],[-221,170]],[[76069,35936],[-115,358],[82,433],[176,283],[29,160],[-182,268],[-28,373],[30,291],[182,376],[-219,255],[-138,494],[-41,392],[246,66],[244,316],[110,559],[4,487],[-102,434],[-108,255],[158,198],[4,112],[-252,274],[-189,143],[-94,191],[-13,340],[135,220],[12,184]],[[44158,27860],[213,-219],[101,-350],[-33,-101],[170,-485],[91,-667],[65,-101],[-3,-722],[144,-351],[-169,-253],[-40,-298],[-207,-43],[116,-352],[-108,-430],[200,-279],[205,-45],[147,-137],[84,33],[214,-191],[198,42],[113,-350],[116,-76],[198,9],[-22,-85],[278,-44],[222,-141],[193,-480],[-11,-241],[56,-186],[282,-402],[150,-71],[12,-420],[140,-645],[58,-598],[127,-114],[32,-352],[135,34],[83,-253],[16,-332],[321,-530],[87,-270],[252,-413],[227,-437],[483,-663],[388,-390],[152,140],[148,305],[270,1],[48,-295],[161,-163],[182,-66],[217,-250],[166,-77],[309,-336],[124,44],[92,-118],[154,113],[195,-18],[139,-156],[364,253],[210,-122],[202,-36],[204,49],[94,-247],[390,-497],[345,58],[403,-177],[346,-18],[184,98],[169,230],[235,98],[-1,221],[103,134],[186,26],[239,329],[253,131],[180,-116],[118,107],[-36,103],[65,243],[225,314],[121,54],[241,-356],[25,-310],[161,-98],[163,-233],[261,4],[219,-69],[309,-239],[220,122],[217,8],[266,154],[45,264],[-50,227],[49,419],[118,445],[201,432],[117,58],[92,432],[-19,683],[-135,134],[-303,72],[-40,274],[62,267],[258,283],[-12,182],[228,234],[-107,333],[-19,215],[-142,335],[241,455],[75,21],[416,676],[138,-100],[219,215],[162,-238],[66,-197],[565,-336],[232,-519],[198,-250],[261,-178],[366,-88],[113,61],[320,624]],[[26409,8966],[-106,95],[86,397],[-509,433],[-136,167],[-109,432],[46,159],[189,176],[261,141],[-100,167],[3,309],[425,170],[147,221]],[[26356,8770],[53,196]],[[23266,14192],[101,-434],[17,-403],[153,-386],[82,-456],[177,-444],[-171,-437],[227,-566],[456,75],[59,-248],[196,163],[30,-232],[172,-114],[41,-553],[195,112],[683,-793],[-69,-31],[10,-301],[134,-259],[84,14],[237,-156],[133,138],[143,-111]],[[26977,12854],[-112,-59],[-337,-13],[-300,184],[-302,93],[-21,286],[-352,-44],[-194,55],[-14,-330],[-122,-405],[-197,174],[-148,-100],[-145,225],[-94,24],[-345,518],[-276,-170],[-120,73],[-189,-87],[-106,337],[-337,577]],[[26606,11833],[186,233],[58,430],[127,358]],[[27830,9691],[-219,214],[-229,332],[-325,-267],[-171,-52],[-61,341],[-266,21],[-73,-74],[-113,286],[-128,181],[629,405],[-268,755]],[[26858,8851],[112,257],[449,-150],[121,59],[74,180],[183,171],[33,323]],[[26409,8966],[85,-59],[364,-56]],[[28859,23840],[-469,319],[-328,1193],[29,907],[-139,133],[34,307],[-144,111],[-139,220],[70,459],[-390,123],[-38,992],[-340,497],[-27,485],[-325,1182],[-104,-45],[-537,286],[-290,286],[-329,-1005],[-432,-744],[-826,-10]],[[28012,18922],[-3,391],[-83,484],[154,232],[283,269],[61,427],[246,395],[15,414],[-68,129],[-125,680],[196,262],[-58,428],[22,206],[103,193],[4,192],[100,216]],[[23284,19157],[530,80],[445,-302],[145,15],[168,-124],[138,38],[323,-156],[193,143],[142,-20],[328,345],[140,20],[229,216],[115,-201],[242,-286],[3,-149],[104,94],[161,-49],[175,97],[279,28],[240,-79],[118,74],[510,-19]],[[24135,29536],[-23,-532],[102,-137],[107,-327],[157,-304],[136,-481],[171,-352],[129,-647],[-109,-162],[-554,-390],[-43,-193],[107,-254],[113,-75],[131,-245],[-17,-123],[-240,-328],[-214,-787],[151,-269],[185,-733],[1,-301],[118,-217],[28,-221],[-142,-246],[-10,-355],[103,-392],[-141,-957],[-165,-334],[-7,-368],[-193,-65],[-152,35],[-94,-177],[-206,-86],[-280,-356]],[[27796,16428],[-2,-244],[-218,-355],[61,-606],[-57,-542],[-194,-480],[67,-201],[-88,-279],[-4,-282],[-258,-192],[-127,-264],[1,-129]],[[27830,9691],[-71,507],[12,269],[140,746],[296,556],[42,256],[-57,282],[88,311],[214,242],[19,323],[-189,792],[-54,326],[32,766],[-84,386],[-342,856],[-80,119]],[[35013,16289],[-240,367],[-32,485],[-112,352],[-360,682],[-463,79],[-229,-173],[-114,-198],[-198,-167],[-228,85],[-124,161],[-249,-132],[-141,292],[-286,271],[-109,-48],[-176,69],[-204,-399],[13,-141],[-323,342],[-210,341],[-333,156],[-152,357],[-80,-219],[-82,-25],[-221,-322],[-11,-99],[-293,-162],[-71,-209],[-190,-10],[-22,-125],[-1082,210],[-358,510],[-69,19]],[[33211,10895],[351,349],[119,401],[10,302],[-45,310],[473,386],[126,462],[87,179],[5,192],[136,235],[343,465],[220,186],[0,307],[-68,301],[-19,365],[-117,385],[181,569]],[[31129,12246],[319,72],[86,119],[257,87],[277,-174],[167,-364],[27,-287],[188,-282],[184,-515],[154,83],[252,-134],[171,44]],[[29320,13605],[665,-305],[224,-338],[283,-312],[199,-16],[136,-120],[93,53],[50,-198],[159,-123]],[[28129,16498],[128,-195],[-44,-168],[177,-489],[177,-208],[-63,-126],[83,-324],[109,-154],[-45,-128],[131,-547],[204,-469],[334,-85]],[[28264,18638],[-124,-588],[38,-250],[23,-981],[-72,-321]],[[34424,22186],[51,91],[-9,392],[-99,186],[133,132],[34,494],[105,37],[23,199],[163,282],[14,250],[-234,174],[-95,180],[-55,323],[-94,266],[234,414],[91,339],[-175,195],[197,180],[-67,312],[10,291],[-103,466],[-160,35],[-98,497],[-134,61],[-230,-129],[-56,89],[-222,67],[-114,418],[-136,104],[-123,211],[-239,191],[-178,245],[-71,221],[-20,308],[44,249],[-117,939],[150,52],[134,244],[541,85],[190,136],[232,261],[260,559],[-4,118],[169,253],[-200,151],[-52,736],[129,282],[-21,305],[68,465],[-117,160],[-64,331],[238,446],[38,231],[-38,208],[237,609]],[[28859,23840],[269,158],[249,-53],[73,54],[414,-208],[285,-61],[291,-134],[334,-220],[64,-91],[223,-50],[256,-216],[158,-66],[192,196],[81,-94],[146,107],[134,-78],[44,-240],[149,-451],[99,-581],[86,-230],[208,-276],[214,71],[375,-111],[371,54],[153,308],[192,119],[86,246],[152,130],[267,63]],[[23469,34080],[219,-109],[158,-178],[-13,-494],[266,-417],[209,-459],[88,-279],[-153,-794],[-11,-500],[-248,-570],[151,-744]],[[28012,18922],[252,-284]],[[35013,16289],[419,202],[123,185],[1,610],[169,279],[45,203],[-151,91],[-146,282],[-115,574],[30,193],[375,627],[-133,535],[-79,83],[82,381],[-88,348],[-394,75],[-354,163],[-245,977],[-128,89]],[[29320,13605],[28,-199],[-102,-125],[-47,-341],[-119,-48],[-27,-232],[-96,43],[-89,-715],[-203,-361],[-260,-748],[600,-311],[942,-590],[68,2],[102,-285],[120,-133],[366,-2],[278,-259],[142,-4],[206,-494],[313,-440],[-70,-117],[59,-351],[-23,-163],[68,-565],[-16,-161],[111,-279]],[[33122,8785],[-390,404],[-450,331],[-131,-75],[-339,519],[-500,588],[69,349],[-454,73],[-291,-89],[-582,45],[-408,-104],[93,942],[320,446],[218,-409],[281,-284],[81,297],[219,281],[271,147]],[[31671,6727],[234,99],[509,383],[140,11],[105,-109],[362,-11],[136,177],[12,441],[50,190],[-47,418],[20,287],[-70,172]],[[30682,4389],[245,231],[74,-38],[332,91],[246,413],[-38,248],[86,467],[156,348],[-108,277],[-4,301]],[[26858,8851],[-79,-185],[185,-358],[112,-103],[401,-662],[153,-462],[199,-338],[580,55],[676,-256],[256,-1],[422,-85],[-44,-619],[-108,-215],[238,-295],[77,-8],[178,-370],[155,-169],[281,-182],[142,-209]],[[28129,16498],[-333,-70]],[[33122,8785],[163,374],[-109,389],[-20,247],[208,622],[-79,392],[-74,86]],[[29127,188],[237,-2],[159,-168],[111,7],[298,629],[353,405],[65,428],[-37,178],[170,318],[-134,233],[-36,513],[140,293],[-28,154],[59,344],[63,83],[135,786]],[[28894,248],[-227,409],[-101,108],[-220,649],[-65,342],[-37,545],[-61,306],[152,317],[-45,1133],[64,439],[514,-781],[42,-330],[-138,-193],[24,-348],[-17,-816],[247,-1032],[44,-384],[82,-310],[-25,-114]],[[24407,4763],[72,-124],[1066,-714],[160,-70],[479,-570],[173,-452],[121,-58],[341,-726],[18,-397],[240,-485],[171,-179],[179,-81],[475,-666],[170,-174],[329,-53],[98,127],[395,107]],[[26356,8770],[-267,-596],[-5,-194],[-144,-159],[42,-316],[-268,-300],[-166,-335],[-163,-205],[-326,-90],[48,-819],[208,102],[297,-32],[131,-112],[-61,-199],[77,-384],[-323,-284],[-184,63],[-71,-103],[-243,74],[-75,-163],[-456,45]],[[23266,14192],[61,629],[-47,349]],[[23280,15170],[-90,-29],[-126,-410],[-131,-233],[-156,-479],[-263,-159],[-85,-138],[32,-488],[214,-1003],[230,-391],[59,-429],[150,-263],[120,-89],[233,-312],[33,-149],[282,-664],[-27,-183],[-31,-2307],[-249,-207],[180,-476],[120,149],[153,31],[190,-879],[69,-602],[220,-697]],[[28894,248],[233,-60]],[[23284,19157],[-100,-6],[18,-263],[-163,-540],[182,-419],[-277,-525],[1,-294],[165,-160],[293,-534],[145,-466],[-150,-674],[-118,-106]],[[86544,52578],[530,-881],[269,-379],[-167,-238],[-173,-439],[-59,-248],[-116,-128],[-173,-652],[-158,-296],[-37,-419],[67,-159],[27,-306],[107,-609],[-27,-136],[136,-378],[426,-349],[114,207],[148,124],[247,349],[142,-32],[156,108],[152,-185],[16,-138],[351,-293],[267,-116],[221,-33],[92,-201],[14,-327],[105,-277],[284,-441],[39,-438],[-104,-334],[95,-214],[332,-94],[326,67],[186,-295],[240,210],[179,11],[329,378],[283,-242],[192,-298],[168,-370],[132,-39],[135,101],[130,285],[204,301],[109,76],[-31,366],[101,354],[155,-52],[499,45],[205,-150],[158,-5],[151,-148],[159,-11],[210,-273],[241,40],[221,-308],[169,-131],[366,-192],[490,435],[102,182],[295,216],[248,13],[118,-230],[699,-809],[179,-426],[511,-383],[119,-26],[266,-287],[171,514],[125,153],[38,300],[-23,230],[363,12],[109,115],[145,10],[93,147],[-80,534],[175,347],[75,442],[93,232],[-226,576],[54,256],[-32,185],[105,115],[27,390],[101,136],[60,275],[223,317],[-87,372],[116,317],[88,650],[-146,88],[-65,200],[30,277],[134,245],[-18,408],[-90,117],[-63,394],[140,373],[203,294],[49,201],[-12,279],[-203,-24],[-227,227],[-136,264],[-1089,1403],[-438,463],[-482,400],[-137,-217],[-470,-29],[-446,-137],[-341,-21],[-516,-365],[-211,-2],[-241,149],[-137,190],[96,241],[-88,556],[-223,403],[-25,380],[-121,182]],[[71110,67447],[-222,447],[-150,177],[-25,252],[-158,380],[83,565],[-166,292],[-57,351],[96,246],[-55,323],[124,544],[-351,100],[-388,497],[5,435],[154,262],[-85,641],[-273,-159],[-209,-189],[-135,-2],[-169,-133],[-315,186],[-266,16],[-392,267],[-198,44],[-384,457],[-353,97],[-256,268],[-195,44],[-201,432],[-75,588],[-288,872],[-158,228],[35,357],[-96,344],[-196,158],[-105,284],[-188,146],[-119,-6],[-358,150],[-223,17],[-164,105],[-130,252],[-293,-2],[-632,-115],[-142,186],[-330,-182],[-371,-153],[-166,-510],[10,-97],[-137,-734],[37,-224],[-111,-338],[-112,-84],[-8,-646],[-79,-61]],[[62170,74822],[24,-393],[105,-537],[-146,-379],[42,-284],[-191,-159],[-310,-423],[-79,-168],[-338,-82],[-232,-255],[-127,-24],[-252,-189],[17,-298],[-368,-537],[-226,-140],[-347,-60],[-121,-73],[-236,-309],[-23,-505],[-143,-347],[-310,-435],[-264,-250],[-239,-135],[-97,-355],[-232,-198],[-88,12],[-41,-260],[479,-743],[-136,-68],[-70,-224],[-90,32],[-213,-150],[-128,-222],[41,-161],[-57,-503],[-274,-419],[9,-438],[-90,-135],[-168,-77],[-68,-127],[-256,-57],[-137,-337],[4,-147],[-202,-82],[-291,-23],[-128,125],[-313,-8],[-106,-350],[-191,-247],[-215,-380],[-294,-208]],[[56544,77784],[72,-222],[319,-38],[233,-140],[278,-251],[172,-371],[96,-72],[142,149],[377,-5],[257,218],[164,66],[149,213],[375,282],[116,-18],[289,209],[113,326],[181,112],[61,165],[236,19]],[[57829,84812],[-250,-503],[-410,-531],[-92,-258],[-27,-309],[-80,-332],[186,-287],[549,-510],[322,-357],[107,-360],[45,-479],[-17,-335],[-228,-324],[-778,-292],[-5,-378],[-108,-398],[-11,-202],[-97,-167],[-18,-343],[-128,-234],[-216,-228],[-29,-201]],[[60042,83112],[-218,33],[-374,229],[104,115],[-149,387],[-4,154],[-273,285],[-40,229],[-251,-11],[-80,76],[-169,-55],[-366,106],[-158,-49],[-235,201]],[[60174,78426],[-78,158],[-22,311],[34,477],[-22,228],[-196,259],[-34,481],[-264,788],[305,345],[-68,469],[90,603],[123,567]],[[55097,78269],[79,229],[12,439],[206,416],[-11,86],[-243,439],[214,280],[112,493],[129,174],[57,265],[93,93],[11,491],[67,330],[-32,233],[-162,390],[-24,397],[-64,203],[72,229],[-187,509],[60,236],[-170,339],[4,349],[111,196],[202,71],[97,191],[-39,213],[226,235],[124,316],[-224,-22],[-296,192],[-219,340],[87,209],[-49,417],[-144,-44],[-605,-19],[249,454],[342,325]],[[52740,78958],[143,-256],[53,-308],[124,-286],[333,-125],[226,-8],[357,111],[424,-18],[434,139],[183,-80],[80,142]],[[52822,84402],[362,-444],[217,-343],[107,-502],[209,-744],[15,-659],[51,-268],[164,-410],[-127,-487],[-249,-239],[3,-224],[-143,-277],[-193,-83],[-352,-350],[-146,-414]],[[54533,88388],[-354,-5],[-153,-443],[-488,148],[-380,2],[-506,-440],[-303,-367],[-43,-394],[56,-674],[454,-449],[-69,-54],[-74,-747],[-127,-130],[276,-433]],[[55182,87963],[-649,425]],[[56463,87625],[27,135],[-119,-15],[-460,139],[-207,162],[-522,-83]],[[57829,84812],[80,234],[-406,316],[-281,581],[-30,191],[-227,-169],[-70,195],[-76,553],[-356,912]],[[55097,78269],[339,179],[392,-339],[194,-283],[185,26],[337,-68]],[[77913,77301],[-275,279],[-25,384],[41,365],[-236,201],[-51,121],[-188,-106],[-150,0],[-339,157],[-339,-95],[-288,23],[-201,-97],[-147,136],[-108,-45],[-223,291],[-7,640],[59,635],[-384,432],[-167,47],[-73,384],[-190,299],[-148,-19],[-163,148],[-32,158],[-175,280],[-121,413],[-169,68],[-196,245],[-130,304],[-140,-161],[-278,25],[-205,-200],[-206,61],[-262,276],[-395,31],[-186,330],[-242,72],[-15,333],[-105,502],[-147,219],[-254,-85],[-74,-200],[-273,-149],[-187,11],[-76,237],[-152,155],[-458,-201],[-231,-237],[-227,94],[-256,-9],[-861,573],[-305,362],[3,116],[-225,304],[-221,-139],[-100,96],[-341,160],[-128,306],[-258,137],[-464,142],[-70,127],[-178,90],[-203,-58]],[[61604,77242],[134,-332],[262,-18],[181,-253],[-84,-367],[-189,-417],[-177,-37],[-93,-306],[-136,-178],[239,-46],[429,-466]],[[61405,83431],[190,-50],[168,-178],[340,-212],[84,-220],[262,-59],[87,-81],[46,-434],[-358,-1297],[156,-108],[190,-266],[22,-187],[-188,-338],[1,-300],[-216,-573],[69,-186],[-80,-455],[-376,-436],[-101,-591],[-97,-218]],[[63568,85948],[-757,-818],[-616,-146],[-177,-216],[-365,-107],[-63,33],[-268,-195],[-28,-656],[-143,-328],[254,-84]],[[65768,86269],[-205,-404],[-110,103],[-191,-37],[-94,113],[-303,53],[-235,-32],[-268,352],[-35,-348],[-72,-230],[-148,-190],[-352,79],[-187,220]],[[61405,83431],[-124,-89],[-307,122],[-202,-60],[-315,-261],[-76,57],[-76,-160],[-263,72]],[[60174,78426],[402,-163],[536,-670],[-64,-102],[60,-295],[102,-83],[394,129]],[[63568,85948],[-86,172],[-390,235],[-212,-3],[-85,254],[-280,-130],[-188,53],[-238,201],[-323,153],[-193,-82],[-180,-462],[-277,-344],[-143,41],[-15,-150],[-174,-196],[-131,-599],[-329,-187],[-76,-355],[-202,-565],[-4,-872]],[[63127,94997],[-208,-473],[-74,-397],[-515,-435],[219,-711],[-18,-165],[82,-264],[-191,-408],[-574,-100],[-95,-79],[-262,20],[-75,75],[-115,-93],[-264,12],[-225,-152],[-321,-118],[-307,-397],[-156,-59],[-210,229],[-82,-25],[-161,-561],[-204,-527],[-17,-271],[-105,-642],[-206,-127],[-167,76],[-125,-153],[-45,-277],[-209,36],[-146,-105],[-16,-147],[-228,-209],[-142,135],[-148,-195],[-198,-561],[-176,-347],[81,-142],[-242,-196],[-165,65],[-300,-20],[-354,336]],[[65768,86269],[75,393],[156,181],[-222,101],[34,129],[-49,299],[9,339],[-109,303],[111,115],[12,325],[73,256],[-83,198],[-225,221],[-115,284],[57,232],[160,240],[31,311],[-83,219],[45,168],[186,195],[36,207],[242,427],[-85,265],[88,248],[376,400],[15,160],[-159,414],[-56,727],[-312,155],[-539,431],[-130,739],[195,116],[127,252],[164,195],[-69,199],[-162,155],[-274,28],[-103,-51],[-416,111],[-101,93],[-139,-495],[-223,-274],[-353,-37],[-275,-134],[-149,-247],[-101,-47],[-151,210],[-150,-28]],[[43801,81202],[119,-596],[-146,-603],[-462,46],[-217,-74],[15,-178]],[[47712,81422],[-172,-49],[-174,109],[-153,-8],[-221,-139],[-254,100],[64,190],[-40,312],[-211,177],[-192,-2],[-195,-319],[-54,-201],[-338,-273],[-290,-173],[-803,-207],[-208,36],[-670,227]],[[50390,77803],[-211,-331],[-178,-137],[-15,-267],[-83,268],[-189,363],[-215,530],[-118,166],[-35,313],[-354,471],[-160,84],[-368,375],[-114,65],[-711,672],[-86,16],[113,403],[46,628]],[[51387,66219],[363,-31],[235,281],[290,84],[1,201],[85,337],[-63,157],[150,478],[55,510],[102,153],[245,199],[192,445],[1,200],[140,354],[93,72],[27,296],[79,116],[-177,449],[-45,337],[-291,4],[-170,111],[-275,456],[-60,285],[-247,247],[-58,220],[45,152],[-2,389],[78,96],[-175,804],[-61,-85],[-211,145],[-131,11],[-23,264],[-120,33],[-23,-149],[-268,200],[38,117],[-267,87],[-161,-45],[-97,186],[-191,-122],[-207,116],[-68,-76],[-45,393],[82,107],[67,589],[222,586],[157,203],[87,373],[-33,461],[-223,588],[-139,200]],[[45558,72563],[361,11],[332,766],[12,113],[248,379],[343,25],[21,-62],[333,37],[64,-62],[314,12],[224,-41],[364,86],[-35,290],[-78,160],[97,227],[217,-274],[183,-23],[166,-179],[407,70],[10,-230],[107,-272],[78,-49],[1,-400],[131,-298],[-40,-583],[118,-434],[-68,-396],[211,-396],[147,-817],[90,-144],[193,-569],[104,19],[73,-171],[19,-303],[-62,-146],[261,-841],[231,-360],[199,75],[86,120],[-57,-401]],[[52740,78958],[-91,-192],[-356,-231],[-52,-165],[-164,-41],[-411,350],[-264,-76],[-95,-149],[-252,-213],[-316,-18],[-137,-134],[-102,-326],[-110,40]],[[50648,84188],[-548,-84],[-536,-151],[-373,-4],[-204,-130],[-463,80]],[[52822,84402],[-189,-68],[-240,30],[-399,-22],[-67,297],[-7,334],[-126,53],[-86,197],[-154,-82],[-3,-350],[155,-430],[170,-218],[-399,-556],[-358,-169],[-471,770]],[[48524,83899],[-80,-509],[-106,-252],[-268,-379],[-202,-524],[-156,-813]],[[45356,86571],[-135,-331],[23,-165],[-173,-130],[49,-165],[-383,-257],[-33,-572],[-127,-303],[-150,-196],[-63,-420],[-69,-185],[53,-540],[516,-357],[-301,-464],[-366,-212],[-162,-268],[-66,-295],[-200,-177],[32,-332]],[[47800,87048],[-531,-180],[-209,-160],[-308,153],[-457,-104],[-258,-187],[-88,44],[-322,-95],[-271,52]],[[48524,83899],[96,775],[1,301],[-64,266],[-112,214],[-340,425],[-191,360],[-92,347],[-22,461]],[[50648,84188],[246,471],[101,3],[-81,465],[189,205],[129,310],[-144,257],[6,182],[-380,388]],[[48087,89336],[-287,-2288]],[[50714,86469],[-191,-249],[-377,-219],[-144,-175],[-200,183],[-367,208],[-241,250],[-282,626],[-492,1013],[-105,836],[-88,-24],[-140,418]],[[45860,93851],[218,326],[180,197],[40,228],[188,323],[410,457],[-10,264],[107,205],[479,345],[356,153],[84,623],[-75,422],[-165,268],[-142,-362],[-323,-428],[-153,-38],[-16,111],[-195,-45],[-322,230],[-145,157],[-138,462],[404,624],[-95,201],[80,148],[53,666],[168,359]],[[46848,99747],[-751,-356],[-124,-309],[-110,-62],[-500,-84],[-151,94],[-19,-331],[-115,-3],[-224,253],[-108,-33],[-285,-805],[-74,16],[-141,359],[14,397],[-187,-58],[-100,-121],[-54,-318],[84,-296],[238,-543],[1377,-2766],[131,-343],[111,-587]],[[46827,95827],[-174,237],[274,97],[-100,-334]],[[49960,98957],[-249,-139],[-64,-98],[-333,37],[-209,-138],[-402,-156],[-253,-261],[-154,-12]],[[48296,98190],[62,-230],[40,-398],[-62,-224],[628,-13],[411,-452],[208,69],[400,-240],[451,-499],[233,-11],[121,-183],[205,11],[308,178],[-227,531],[-373,446],[-67,272],[-16,433],[-181,66],[-61,170],[-156,167],[-105,463],[-155,211]],[[48293,91259],[-16,130],[248,248],[498,258],[40,393],[-108,297],[161,309],[-31,173],[151,221],[24,149],[188,75],[449,526],[106,233],[183,174],[49,219],[187,99],[194,-342],[245,-118]],[[51519,95859],[-118,41],[-168,-132],[-321,104],[-230,-364],[-213,-169],[-102,5],[-316,-165],[-192,-15],[-368,-415],[-159,-230],[9,-135],[-130,-15],[62,336],[119,253],[-2,552],[77,206],[-104,186],[56,123],[-320,88],[-286,-164],[-108,-193],[-200,36],[-64,-203],[91,-93],[-169,-712],[-268,-459],[-46,-394],[-67,-160],[161,-40],[-155,-246],[-183,-121],[-169,-238],[121,-122],[-159,-220],[176,-350],[276,-374],[156,-269],[87,-532]],[[50861,94303],[185,160],[153,289],[86,22],[321,431],[526,278],[95,199],[-708,177]],[[51519,95859],[-51,406],[329,201],[125,135],[96,364],[310,21],[249,-60],[-18,690],[19,1093]],[[48766,89385],[-60,139],[-435,114],[-44,306],[276,207],[235,27],[-3,412],[-228,292],[-214,377]],[[48087,89336],[679,49]],[[47837,90191],[180,-324],[69,-230],[1,-301]],[[45860,93851],[54,-190],[585,-1184],[1338,-2286]],[[48296,98190],[-126,188],[-68,312],[-21,431],[-241,434],[-232,147],[-272,297],[-488,-252]],[[52578,98709],[-208,-58],[-566,113],[-272,118],[-84,184],[-270,245],[-208,342],[-196,103],[-193,-318],[-96,-9],[-234,-198],[-101,-11],[-190,-263]],[[51262,90022],[38,180],[-432,180],[-426,335],[-48,207],[41,171],[-153,72],[96,324],[-58,33],[65,326],[166,261],[-202,282],[146,240],[86,378],[-46,132],[122,613],[-100,148],[168,49],[158,209],[-22,141]],[[48766,89385],[946,131],[177,52],[500,246],[607,242],[266,-34]],[[50714,86469],[-37,192],[-178,162],[10,137],[239,461],[-18,405],[127,471],[-17,139],[196,450],[48,250],[-62,217],[390,370],[-206,254],[56,45]],[[47837,90191],[-230,-261],[-343,26],[-335,-98],[-128,-163],[-172,7],[-215,-253],[-83,-326],[80,-258],[-49,-166],[74,-787],[-177,-173],[-517,-109],[-68,-60],[-69,-468],[-159,7],[-90,-538]],[[58386,96143],[-195,70],[-335,-19],[-285,72],[-233,-183],[-344,-4],[-152,-160],[-81,212],[-550,-171],[-193,-2],[-134,174],[-128,-133],[-225,196],[-414,-52],[-814,-831],[-337,-215],[-103,-157],[-41,-488],[-221,-221],[21,-355],[-59,-153],[82,-254],[-84,-122],[43,-124],[-201,-269],[81,-199],[13,-455],[52,-164],[-275,-215],[37,-192],[-158,-435],[89,-324],[-739,-905],[-282,149],[-238,61],[-501,-151],[-220,-102]],[[54533,88388],[37,304],[208,550],[-325,-10],[-38,90],[3,661],[-322,42],[39,652],[125,182],[265,-148],[288,185],[183,421],[149,59],[131,256],[325,296],[153,286],[20,197],[361,255],[128,278],[80,317],[123,236],[239,58],[180,127],[309,-68],[380,361],[46,759],[105,174],[354,352],[44,369],[263,514]],[[60511,97553],[-368,-665],[-638,-282],[-567,76],[-232,-48],[-320,-491]],[[63127,94997],[-114,272],[-159,84],[-97,215],[-474,305],[-167,-97],[-35,88],[-277,204],[-141,232],[-170,161],[24,89],[-525,282],[-165,373],[-207,186],[-20,179],[-89,-17]],[[60511,97553],[-115,-48],[-153,88],[-494,0],[-510,-217],[-144,60],[-225,-134],[-285,26],[-159,480],[-132,0],[-24,130],[-192,-95],[-196,37],[-167,122],[-357,47],[-344,-89],[-96,165],[-425,224],[-126,139],[-63,221],[153,152],[-57,235],[-320,-191],[-218,12],[-277,233],[-234,61],[-340,400],[-17,348],[-109,8],[-210,-191],[-353,-160],[-127,69],[-221,-54],[-202,-150],[-254,1],[-297,119],[-203,21],[-201,-519],[13,-137],[-252,-257]],[[16391,70076],[-33,-239],[107,-631],[90,-152],[43,-422],[367,-352],[8,-227],[297,-114],[7,-65],[248,69],[196,-12],[291,196],[217,-135],[272,-725],[443,-312],[373,-301],[120,-175],[164,-390],[163,22],[175,-587],[0,-459],[133,-314],[82,-329],[173,-213],[51,-186],[242,-224],[-140,-263],[-307,-432],[60,-401],[261,-330]],[[22110,78045],[-236,-120],[-354,-623],[-325,-148],[-170,-234],[3,-550],[-41,-500],[110,-540],[-34,-109],[-254,-211],[-163,-304],[-198,-678],[42,-410],[-234,-263],[-137,-348],[-99,-473],[-212,-444],[-70,-492],[-583,-698],[-548,-55],[-424,-234],[-285,-49],[-269,-145],[-208,42],[-429,-152],[-160,10],[-441,-241]],[[20494,62373],[260,562],[-27,133],[-212,-73],[-36,132],[265,156],[170,216],[193,101],[159,348],[463,295],[117,13],[320,177],[266,-182],[464,38],[472,169],[645,147],[291,227],[111,-25],[464,320],[41,135],[116,-68],[22,198],[186,148],[132,402],[257,102],[192,-30],[40,98],[-82,262]],[[8392,55182],[163,-17],[367,89],[183,-65],[325,35],[254,-92],[26,155],[347,337],[120,198],[813,855],[54,186],[270,23],[265,-191],[186,263],[273,258],[689,172],[673,131],[314,-159]],[[6982,61391],[-147,-181],[6,-335],[-95,-372],[-106,-28],[-171,-239],[24,-315],[-59,-188],[39,-273],[109,-317],[268,-559],[355,-253],[255,-394],[86,-63],[376,-465],[125,-208],[337,-1908],[8,-111]],[[14060,70758],[-122,17],[-315,-146],[-311,176],[-42,192],[-106,79],[-380,-102],[-157,109],[-243,-38],[-372,-145],[-147,-450],[-255,-255],[-184,4],[-333,-123],[-124,-276],[-265,-400],[-281,-194],[-14,-171],[70,-334],[-386,22],[-134,152],[-251,-16],[-176,-276],[-138,-53],[-94,-423],[87,-237],[73,-482],[-61,-294],[77,-224],[69,-425],[-2,-240],[235,-471],[-152,-283],[-343,180],[-150,-273],[-217,-130],[6,-452],[-132,-144],[-123,-481],[28,-315],[-194,-566],[42,-363],[106,-477],[-236,-252],[-270,-129],[-215,-287],[-259,24],[-467,-220],[-220,-175]],[[13714,57360],[-91,1084],[119,416],[-129,70],[28,173],[-143,905],[-207,511],[52,84],[-160,182],[-80,325],[93,346],[-21,253],[88,354],[-5,315],[-78,134],[26,203],[-46,373],[-116,246],[10,208],[-168,555],[-169,361],[-364,604],[-248,316],[124,408],[172,232],[101,760],[-160,673],[58,410],[155,200],[153,368],[34,324],[-49,237],[39,496],[1328,1272]],[[17271,50970],[-80,531],[-145,450],[-77,1027],[-161,527],[-231,113],[-212,365],[-354,-198],[-191,-43],[-181,154],[-279,-63],[-220,-260],[-178,39],[-99,-127],[-139,28],[-308,-110],[-145,141],[-190,9],[-117,300],[62,185],[-10,229],[108,197],[4,326],[-142,166],[-193,370],[77,279],[-19,215],[-112,242],[174,350],[-174,723],[-25,225]],[[5489,44488],[243,-222],[203,-72],[166,91],[2123,-1166],[1561,935],[9,-420],[115,-402],[366,-76],[259,28],[667,781],[98,-32],[225,139],[67,214],[378,65],[382,134],[131,331],[533,184],[248,318],[526,251],[475,629],[195,358],[-52,330],[92,88],[-111,308],[-122,102],[-174,295],[-132,313],[-87,384],[-12,316],[59,336],[198,170],[55,228],[375,124],[116,238],[204,141],[68,-170],[399,-65],[455,-258],[298,431],[178,190],[56,467],[-39,193],[101,287],[253,-233]],[[8392,55182],[-19,-821],[-51,-409],[-62,-177],[-160,-206],[-152,-53],[-100,-228],[-18,-273],[-117,-341],[-124,-115],[-79,-369],[116,-232],[-151,-263],[-141,-415],[38,-226],[-61,-374],[241,-672],[-64,-224],[32,-196],[-105,-126],[26,-384],[-97,-507],[-178,-25],[-110,72],[-80,-106],[-100,-336],[-175,-259],[-158,-98],[-81,-465],[-224,-538],[-304,-180],[-170,-592],[-26,-190],[-230,-695],[31,-168],[-69,-333],[19,-170]],[[14808,69149],[-88,142],[-165,56],[-197,-27],[-216,96],[-142,346],[107,354],[-86,359],[39,283]],[[19419,56678],[-104,236],[-222,71],[-103,269],[-184,184],[-19,-103],[-603,-179],[-371,69],[-196,386],[-342,123],[-267,-15],[-55,133],[13,424],[-40,248],[16,416],[83,71],[31,228],[-46,303],[92,216],[185,88],[-284,1596],[-32,329],[112,488],[-120,184],[-162,-71],[-230,1073],[16,176],[-89,232],[147,595],[-79,214],[-635,1334],[-64,447],[-227,312],[-62,217],[-288,38],[-170,232],[37,85],[-85,533],[-51,54],[-161,800],[-52,435]],[[19843,55982],[-187,265],[-237,431]],[[6982,61391],[-83,320],[-173,109],[-97,404],[-119,198],[-43,226],[-184,128],[5,377],[-189,44],[-534,-465],[-169,-289],[-286,-254],[-19,-290],[-92,-199],[-55,-294],[225,-704],[38,-193],[-80,-263],[-360,-427],[-179,-65],[-230,-251],[-296,-495],[-172,-89],[-233,22],[-131,-96],[-23,-389],[-440,-412],[-431,482],[-140,6],[-322,-188],[-53,-97],[-118,-537],[-161,-224],[-310,90],[-230,-98],[-142,-370],[11,-295],[73,-463],[-115,-316],[78,-319],[-34,-633],[33,-215],[172,-285],[85,-422],[-172,-158],[-205,-444],[-286,-332],[-261,0],[-347,-679],[196,-307],[-105,-441],[60,-174],[-93,-213],[-206,-203],[-40,-372],[304,-355],[80,-306],[0,-265],[72,-135],[254,-195],[9,-160],[207,-171],[193,-50],[290,46],[117,-438],[-46,-736],[107,-413],[-121,-339],[2,-478],[185,-354],[0,-223],[80,-498],[-161,-1039],[179,-67],[194,215],[268,1],[110,-79],[315,161],[48,-178],[202,-74],[101,-176],[33,-369],[237,-40],[117,-129],[313,-114],[253,229],[104,197],[202,221],[66,-104],[452,-264],[92,-132],[266,10],[365,452]],[[19419,56678],[365,1132],[12,420],[-110,635],[4,208],[-111,216],[31,184],[-20,457],[-78,363],[8,784],[-45,148],[92,295],[360,330],[259,136],[308,387]],[[16391,70076],[-241,53],[-136,-256],[-315,-54],[-251,-326],[-290,-90],[-350,-254]]],"transform":{"scale":[0.006752240833643487,-0.004800048000480004],"translate":[142.39133443824244,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/ju.json b/src/onegov/election_day/static/mapdata/2025/ju.json new file mode 100644 index 0000000000..c24f9c1ead --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/ju.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":6702,"properties":{"id":6702,"name":"Boécourt"},"arcs":[[-1,-2,-3,-4,-5]]},{"type":"Polygon","id":6703,"properties":{"id":6703,"name":"Bourrignon"},"arcs":[[-6,-7,-8,-9,1]]},{"type":"Polygon","id":6704,"properties":{"id":6704,"name":"Châtillon (JU)"},"arcs":[[-10,-11,-12,-13,-14]]},{"type":"Polygon","id":6706,"properties":{"id":6706,"name":"Courchapoix"},"arcs":[[-15,-16]]},{"type":"Polygon","id":6708,"properties":{"id":6708,"name":"Courrendlin"},"arcs":[[-17,-18,12,-19,-20,-21]]},{"type":"Polygon","id":6709,"properties":{"id":6709,"name":"Courroux"},"arcs":[[20,-22,-23,-24,-25]]},{"type":"Polygon","id":6710,"properties":{"id":6710,"name":"Courtételle"},"arcs":[[-26,10,-27,-28,-29]]},{"type":"Polygon","id":6711,"properties":{"id":6711,"name":"Delémont"},"arcs":[[21,19,-30,28,-31,7,-32,-33]]},{"type":"Polygon","id":6712,"properties":{"id":6712,"name":"Develier"},"arcs":[[-34,2,8,30,27]]},{"type":"Polygon","id":6713,"properties":{"id":6713,"name":"Ederswiler"},"arcs":[[-35,-36,-37]]},{"type":"Polygon","id":6715,"properties":{"id":6715,"name":"Mervelier"},"arcs":[[-38,-39]]},{"type":"Polygon","id":6716,"properties":{"id":6716,"name":"Mettembert"},"arcs":[[-40,-41,-42,31]]},{"type":"Polygon","id":6718,"properties":{"id":6718,"name":"Movelier"},"arcs":[[-43,40,-44,35,-45]]},{"type":"Polygon","id":6719,"properties":{"id":6719,"name":"Pleigne"},"arcs":[[-46,36,43,39,6,-47]]},{"type":"Polygon","id":6721,"properties":{"id":6721,"name":"Rossemaison"},"arcs":[[29,18,11,25]]},{"type":"Polygon","id":6722,"properties":{"id":6722,"name":"Saulcy"},"arcs":[[-48,-49,-50,-51]]},{"type":"Polygon","id":6724,"properties":{"id":6724,"name":"Soyhières"},"arcs":[[32,41,42,-52,22]]},{"type":"Polygon","id":6729,"properties":{"id":6729,"name":"Haute-Sorne"},"arcs":[[-53,48,-54,-55,3,33,26,9]]},{"type":"Polygon","id":6730,"properties":{"id":6730,"name":"Val Terbi"},"arcs":[[16,24,-56,15,-57,38,-58]]},{"type":"Polygon","id":6741,"properties":{"id":6741,"name":"Le Bémont (JU)"},"arcs":[[-59,-60,-61,-62]]},{"type":"Polygon","id":6742,"properties":{"id":6742,"name":"Les Bois"},"arcs":[[-63,-64]]},{"type":"Polygon","id":6743,"properties":{"id":6743,"name":"Les Breuleux"},"arcs":[[-65,-66,-67,-68,-69]]},{"type":"MultiPolygon","id":6745,"properties":{"id":6745,"name":"Les Enfers"},"arcs":[[[-70,-71,58,-72,-73,-74]],[[-75]]]},{"type":"Polygon","id":6748,"properties":{"id":6748,"name":"Les Genevez (JU)"},"arcs":[[-76,-77,-78]]},{"type":"Polygon","id":6750,"properties":{"id":6750,"name":"Lajoux (JU)"},"arcs":[[76,-79,-80,50,-81]]},{"type":"Polygon","id":6751,"properties":{"id":6751,"name":"Montfaucon"},"arcs":[[-82,59,70,-83,73,-84,-85,-86,78,75]]},{"type":"MultiPolygon","id":6753,"properties":{"id":6753,"name":"Muriaux"},"arcs":[[[-87,-88,65]],[[68,-89,-90]]]},{"type":"Polygon","id":6754,"properties":{"id":6754,"name":"Le Noirmont"},"arcs":[[89,-91,62,-92,-93,86,64]]},{"type":"Polygon","id":6757,"properties":{"id":6757,"name":"Saignelégier"},"arcs":[[61,-94,66,87,92,-95,-96,71],[74]]},{"type":"MultiPolygon","id":6758,"properties":{"id":6758,"name":"Saint-Brais"},"arcs":[[[79,85,-97,53,47]],[[82,69]]]},{"type":"Polygon","id":6759,"properties":{"id":6759,"name":"Soubey"},"arcs":[[83,72,95,-98,-99]]},{"type":"Polygon","id":6771,"properties":{"id":6771,"name":"Alle"},"arcs":[[-100,-101,-102,-103,-104,-105]]},{"type":"Polygon","id":6774,"properties":{"id":6774,"name":"Boncourt"},"arcs":[[-106,-107]]},{"type":"Polygon","id":6778,"properties":{"id":6778,"name":"Bure"},"arcs":[[-108,-109,-110,-111,-112,-113,-114]]},{"type":"Polygon","id":6781,"properties":{"id":6781,"name":"Coeuve"},"arcs":[[-115,-116,-117,99,-118,-119]]},{"type":"Polygon","id":6782,"properties":{"id":6782,"name":"Cornol"},"arcs":[[-120,-121,102,-122]]},{"type":"Polygon","id":6783,"properties":{"id":6783,"name":"Courchavon"},"arcs":[[118,-123,107,-124]]},{"type":"Polygon","id":6784,"properties":{"id":6784,"name":"Courgenay"},"arcs":[[-125,103,120,-126,-127]]},{"type":"Polygon","id":6785,"properties":{"id":6785,"name":"Courtedoux"},"arcs":[[-128,-129,109,-130]]},{"type":"Polygon","id":6789,"properties":{"id":6789,"name":"Fahy"},"arcs":[[-131,111,-132,-133]]},{"type":"Polygon","id":6790,"properties":{"id":6790,"name":"Fontenais"},"arcs":[[126,-134,-135,-136,127,-137]]},{"type":"Polygon","id":6792,"properties":{"id":6792,"name":"Grandfontaine"},"arcs":[[132,-138,-139]]},{"type":"Polygon","id":6800,"properties":{"id":6800,"name":"Porrentruy"},"arcs":[[124,136,129,108,122,117,104]]},{"type":"Polygon","id":6806,"properties":{"id":6806,"name":"Vendlincourt"},"arcs":[[100,116,-140,-141,-142,-143]]},{"type":"Polygon","id":6807,"properties":{"id":6807,"name":"Basse-Allaine"},"arcs":[[-144,-145,114,123,113,-146,105]]},{"type":"Polygon","id":6808,"properties":{"id":6808,"name":"Clos du Doubs"},"arcs":[[54,96,84,98,-147,133,125,119,-148,4]]},{"type":"Polygon","id":6809,"properties":{"id":6809,"name":"Haute-Ajoie"},"arcs":[[-149,137,131,110,128,135]]},{"type":"Polygon","id":6810,"properties":{"id":6810,"name":"La Baroche"},"arcs":[[121,101,142,-150,46,5,0,147]]},{"type":"Polygon","id":6811,"properties":{"id":6811,"name":"Damphreux-Lugnez"},"arcs":[[-151,139,115,144,-152]]},{"type":"Polygon","id":6812,"properties":{"id":6812,"name":"Basse-Vendline"},"arcs":[[-153,140,150]]}]}},"arcs":[[[54055,65489],[-444,224],[-36,-127],[-275,-45],[-246,-254],[-88,-286],[-154,-821],[-162,-243],[-343,-633],[-457,-578]],[[57479,63738],[-10,313],[-455,239],[-449,332],[-285,146],[-196,16],[-1008,294],[-709,267],[-312,144]],[[57217,60389],[-206,255],[-408,1019],[-5,380],[93,400],[149,407],[94,144],[-173,347],[-8,350],[443,-42],[283,89]],[[48935,55715],[735,-558],[257,-152],[303,-285],[144,-42],[725,-581],[30,232],[171,-195],[380,-327],[537,-207],[14,97],[436,-84],[370,-315],[323,37],[107,184],[291,170],[120,237],[139,504],[181,524],[217,751],[25,272],[170,213],[307,275],[191,425],[84,404],[125,260],[87,328],[255,300],[635,471],[322,277],[177,226],[68,241],[356,992]],[[51850,62726],[47,-233],[10,-402],[124,-242],[-122,-481],[-175,-429],[-262,-389],[-171,-328],[-202,-273],[-349,-225],[-268,-419],[-288,244],[-176,-541],[-183,-692],[-97,-519],[-165,-513],[-153,-138],[-485,-1431]],[[55220,73378],[-271,-204],[-331,37],[-359,-561],[-509,-669],[-286,-329],[-17,-938],[27,-429],[118,-414],[188,-1308],[271,-941],[371,-1224],[-92,-126],[-108,-356],[-152,-196],[-15,-231]],[[63874,68188],[-556,149],[-1381,-179],[-273,-1],[-285,-62],[-364,540],[-297,810],[130,71],[-241,315],[-140,-6],[-156,333],[-168,227],[-295,553],[-108,807],[-420,187],[-323,569],[-234,26],[-464,-105],[-332,48],[-288,477],[-247,351],[-298,167],[-533,-456],[-46,-100],[-481,26],[-332,-121],[-101,19],[-421,545]],[[62843,64553],[23,233],[-125,213],[-10,446],[42,245],[212,547],[525,434],[324,1009],[40,508]],[[57479,63738],[625,431],[407,124],[301,30],[685,188],[380,25],[452,-22],[44,80],[757,-48],[630,-99],[475,79],[534,139],[74,-112]],[[68972,43698],[322,-74]],[[69015,52905],[-1,-458],[145,-244],[-604,-63],[26,-237],[601,77],[-143,-211],[-12,-754],[-62,-265],[-38,-876],[1,-601],[98,-508],[47,-1061],[18,-70],[229,3],[-9,-547],[-128,-233],[-352,-840],[-168,-253],[-129,-12],[39,-265],[231,-548],[98,-546],[70,-695]],[[71540,52170],[-241,-119],[-267,150],[90,339],[-407,290],[-792,51],[-908,24]],[[70935,43609],[-133,407],[53,502],[270,65],[734,400],[-32,811],[168,292],[19,629],[-30,876],[-176,730],[-36,497],[5,586],[-59,1319],[-178,1447]],[[69294,43624],[239,-106],[452,40],[453,-102],[497,153]],[[86122,62060],[-238,106],[-278,205],[-166,354]],[[85440,62725],[-584,-693],[-202,-540],[-113,-426],[-133,-732],[-9,-269],[-260,-1417],[2,-1035],[-80,-31],[-286,-1179],[-74,-29],[-153,-374],[-107,-418],[63,-296],[-41,-137],[-277,147],[208,-771],[-181,-90],[105,-340],[307,-769],[210,-642],[73,-662],[90,-315],[-50,-323],[69,-479],[190,-90],[264,-255],[122,-296],[252,-422],[199,473],[279,139],[141,131],[401,184],[462,134],[259,139],[358,279],[-277,431],[-30,298],[82,760],[66,860],[-289,77],[-76,137],[21,192],[179,-5],[108,313],[8,325],[351,-8],[0,357],[-132,96],[6,140],[-324,71],[-46,511],[390,-2],[-62,431],[-174,184],[-120,10],[84,254],[-1,584],[666,33],[9,126],[-257,460],[-850,-31],[-52,509],[-325,823],[-14,707],[387,186],[-39,52],[-75,1003],[-36,855]],[[83877,44385],[-149,3180],[6,426],[-39,650],[-119,905],[11,177],[-332,194],[-377,131],[-530,326],[-537,214],[-357,-78],[-520,23],[-185,177],[-490,256],[-363,312],[-369,-550],[-341,193],[62,228],[-77,209],[-241,320]],[[70935,43609],[390,252],[451,203],[87,2],[604,328],[183,-21],[533,236],[523,426],[327,351],[425,382],[557,412],[242,-268],[349,-1],[230,-163],[299,59],[262,-85],[205,31],[67,-107],[394,116],[394,-32],[239,-77],[234,18],[372,-128],[495,-29],[412,173],[405,18],[117,-480],[62,-461],[476,-217],[122,35],[352,-199],[257,-447],[587,202],[403,-150],[433,52],[300,95],[1154,250]],[[71389,55393],[-123,-190],[85,-410],[-16,-123],[301,-923],[33,-535],[-139,-869],[10,-173]],[[72916,57746],[-429,-54],[-11,-114],[-270,-102],[3,-268],[-72,-209],[56,-284],[-55,-91],[9,-499],[-31,-105],[-250,-114],[-124,-161],[-33,-294],[-320,-58]],[[78930,51678],[-197,143],[-511,-390],[-488,-260],[-236,-577],[36,723],[-280,503],[-146,348],[-72,587],[-222,823],[29,373],[-285,774],[-167,579],[-300,793],[-505,503],[-323,-431],[-605,699],[172,437],[-161,171],[-410,11],[-14,-268],[-275,4],[-77,-379],[-245,-102],[37,-169],[-200,120],[-63,221],[-352,294],[-154,538]],[[73329,66895],[45,-294],[-503,-849],[-196,-421],[-239,-765],[-29,-299],[57,-234],[254,-389],[-3,-503],[-166,-951],[124,-551],[59,-688],[-31,-441],[24,-206],[124,-212],[91,10],[281,235],[154,-473],[-17,-616],[-476,-1342],[34,-160]],[[79889,67241],[-333,177],[-224,-24],[-220,125],[-211,5],[-377,103],[-108,101],[-166,439],[-434,-55],[-16,-263],[-136,-162],[-46,-200],[89,-158],[276,-115],[41,-111],[-62,-495],[-310,59],[-188,107],[-483,871],[5,226],[-208,-64],[-262,-169],[-185,67],[-259,-125],[-303,-23],[-185,-79],[-132,121],[-343,-9],[-122,-278],[-179,-140],[-369,-152],[-354,-10],[-459,64],[-297,-179]],[[83009,64037],[167,787],[-507,-414],[-1212,34],[-687,90],[-1158,205],[641,1194],[-341,1089],[-23,219]],[[78930,51678],[-188,436],[-168,241],[-406,1231],[-41,-30],[-79,626],[-5,318],[64,292],[-58,322],[-89,765],[-116,75],[26,298],[128,718],[-167,213],[74,538],[102,-122],[132,32],[416,-461],[90,151],[169,22],[-49,138],[161,35],[-43,204],[492,85],[13,-113],[645,-99],[38,298],[100,335],[143,243],[-4,275],[350,381],[625,1150],[229,524],[147,455],[55,754],[332,878],[179,89],[403,416],[379,646]],[[69015,52905],[-90,557],[44,15],[-105,829],[-95,321],[-64,993]],[[63693,55931],[-34,-316],[141,-850],[-257,-176],[263,-933],[159,69],[215,-1161],[-91,-98],[27,-335],[99,55],[95,-1334],[-24,-1131],[-41,-365],[-46,-1422],[-16,-1508],[-53,-782],[-145,-924],[316,-168],[916,-174],[477,-114],[220,-9],[612,-161],[330,-32],[377,-140],[637,-178],[414,-30],[643,-94],[45,78]],[[65777,57582],[-348,-191],[20,-285],[-91,-34],[-78,-257],[75,-47],[-156,-221],[-260,60],[-340,-113],[-463,-227],[-443,-336]],[[68705,55620],[-88,444],[-288,17],[-197,263],[-308,134],[-359,444],[414,780],[-27,146],[-238,368],[-318,246],[-433,162],[-402,41],[-18,-886],[-356,-34],[-63,-391],[-247,228]],[[68705,55620],[1090,202],[-80,444],[481,141],[251,140],[290,97],[397,-880],[128,11],[127,-382]],[[62843,64553],[465,-674],[439,-950],[678,-866],[74,-271],[69,-637],[304,12],[84,-170],[178,80],[115,-382],[226,-220],[87,18],[429,-331],[16,-504],[58,17],[5,-1047],[-48,-4],[-23,-411],[-120,-433],[-102,-198]],[[72384,68984],[-202,-47],[-362,107],[-257,-11],[-307,-120],[-309,-30],[-473,95],[-448,-70],[-770,-76],[-211,19],[-471,-125],[-1049,4],[-535,-166],[-470,59],[-334,-12],[-676,354],[-196,175],[-262,-8],[-315,-431],[-93,196],[-249,-270],[-521,-439]],[[73329,66895],[-75,125],[-623,135],[112,106],[405,113],[363,288],[59,287],[144,327],[-83,275],[-383,101],[-337,-96],[-352,233],[-144,25],[-31,170]],[[57217,60389],[731,-191],[178,-124],[305,-354],[121,-205],[127,-348],[291,-339],[116,-219],[455,-534],[254,-158],[236,-311],[56,-539],[136,-564],[440,-594],[567,-268],[364,-405],[318,-134],[481,29],[436,181],[231,186],[387,236],[246,197]],[[72070,74484],[84,446],[14,446],[-363,166],[-263,266],[-187,288],[-373,169],[-143,400],[-345,205],[20,73],[-263,207],[-81,417],[-316,185],[-29,394],[-56,144],[65,187],[-161,191],[-258,-45],[-38,135],[-791,29],[-424,349],[-402,178]],[[65972,76303],[287,-553],[386,-555],[283,-6],[1124,-252],[532,73],[308,-13],[377,86],[317,-31],[606,-128],[168,-67],[297,112],[306,-44],[79,-111],[250,-126],[183,20],[595,-224]],[[67760,79314],[-62,-3],[17,-722],[-203,-57],[-77,-220],[-120,-90],[-371,-609],[-84,-399],[0,-334],[-290,-165],[-304,-278],[-294,-134]],[[95747,48363],[358,1381],[238,727],[198,322],[154,831],[-17,100],[764,731],[347,279],[389,420],[378,275],[272,84],[2,591],[153,219],[156,450],[-113,16],[-427,302],[-155,40],[-314,243],[-430,95],[-165,-112],[-223,48],[-129,486],[-177,259]],[[97006,56150],[-416,-244],[-568,-185],[-246,-41],[-231,-180],[-334,-118],[-138,127],[-589,102],[-324,86],[-410,679],[-348,367],[-135,28],[-361,368],[-450,18],[-213,82],[-391,-127],[-279,-132],[-632,-500],[-732,-264],[65,-384],[-329,-235],[67,-374],[114,-24],[3,-165],[-167,28],[83,-1029],[-24,-2],[5,-655],[53,-161],[16,-1083],[42,-58],[828,14],[401,58],[344,97],[470,-1097],[498,-1094],[43,-139],[329,-298],[1566,-364],[1131,-888]],[[64263,70647],[100,-942],[-274,-956],[-215,-561]],[[70796,70135],[-744,99],[-357,-17],[-449,63],[-858,-131],[-1111,88],[-431,-16],[-351,49],[-56,-56],[-452,126],[-431,-93],[-345,12],[-470,114],[-335,133],[-143,141]],[[72384,68984],[-61,276],[-107,79],[-66,208],[50,220],[-231,177],[-57,-149],[-808,199],[-308,141]],[[70796,70135],[180,796],[247,183],[541,584],[188,306],[483,898],[266,707],[171,785]],[[65972,76303],[-56,-89],[-344,-180],[-231,305],[-264,-124],[-363,-1034],[180,-54],[-62,-208],[20,-635],[120,-76],[-1089,-263],[65,-176],[375,-637],[51,-477],[-27,-972],[-256,-161],[63,-204],[48,-503],[61,-168]],[[72872,74394],[-608,136],[-194,-46]],[[67760,79314],[-79,366],[-50,481],[157,339],[103,84],[140,413],[-124,578],[-195,-174],[-103,32],[-230,-247],[-103,72],[-323,-155],[-154,133],[-217,-52],[-178,36],[-313,-66],[-217,-156],[-325,48],[-298,195],[-165,41],[-627,-95],[-260,-609],[-141,-117],[-506,-108],[-148,-371],[-299,-287],[-148,65],[-433,347],[-407,121],[-315,-53],[-254,-125],[-79,-306],[-166,-230],[-242,-64],[-61,-199],[-147,-109],[-343,-385],[-166,-356],[-183,-287],[-262,-220],[-550,-94],[-390,-207],[-485,-151],[-535,-233],[-409,-315],[-293,-120],[24,-81],[-160,-361],[-398,-302],[-158,200]],[[56545,76230],[-155,-362],[-73,51],[-359,-385],[-298,-490],[-164,-3],[-364,-274],[-147,11],[89,-503],[-18,-428],[164,-469]],[[41476,42024],[-318,-109],[-290,-195],[-225,-45],[-324,-213],[-118,48],[62,-475],[-251,-10],[-210,-272],[-279,-140],[-43,-185],[99,-121],[178,-28],[104,-256],[-153,-183]],[[46618,40374],[204,359],[91,290],[83,874],[139,182],[725,1167],[266,181],[133,278],[-45,162],[34,485],[182,396],[283,263],[331,-6],[49,304],[-337,445],[-186,102],[-210,307],[-312,217],[-476,87],[-212,-14],[-65,113],[-682,396],[-285,-77],[-175,-221],[-15,-148],[-143,76],[-122,585],[-507,-513],[-197,-274],[-224,90],[-257,-229],[-406,-546],[-175,-403],[104,-391],[-581,-358],[-445,-186],[243,-571],[-143,-268],[-416,-554],[-104,-60],[-184,-351],[17,-124],[-416,-354],[-174,-9],[-247,-120],[-220,-23],[-65,91]],[[45071,40077],[56,274],[572,60],[129,62],[744,-131],[46,32]],[[39708,39840],[82,-287],[-32,-345],[882,155],[407,-10],[235,-232],[172,206],[129,292],[-31,314],[84,284],[318,271],[487,36],[-176,-472],[2,-651],[150,-73],[329,-265],[220,60],[214,-285],[81,-340],[309,-239],[133,159],[111,-176],[134,671],[-288,397],[371,400],[-21,383],[304,175],[-26,176],[519,-169],[264,-198]],[[79889,67241],[33,1113],[127,169],[-73,128],[-248,113],[-292,-18],[-190,82],[-373,18],[-162,62],[-238,227],[-285,181],[-342,22],[-163,655],[-254,1197],[-298,-11],[-276,-90],[-430,-1],[-136,329],[-211,896],[-223,846],[-72,572],[-636,118],[-201,104],[-288,272],[-282,1],[-312,-75],[-487,47],[-705,196]],[[46618,40374],[245,10],[18,85],[573,109],[677,89],[333,-124],[945,285],[416,26],[381,-57],[793,-73],[442,-217],[-270,-427],[-144,-341],[105,-253],[201,-327],[245,-313],[450,265],[203,54],[1192,-523],[1228,10],[198,-164],[530,-328],[277,-212],[427,-143],[502,7],[442,48],[496,-75],[741,120],[7,336],[372,125],[278,-37],[225,-98],[460,-271],[815,-321],[559,-147],[200,16],[695,240],[250,29],[23,201],[215,-109],[579,79],[396,159],[177,27],[262,141],[526,159],[49,75],[194,-43],[487,77],[307,178],[24,106],[181,100],[375,102],[512,207],[521,1012],[272,442],[503,408],[758,753],[116,565],[265,393],[427,815]],[[43642,48583],[-81,-127],[-213,-631],[-195,-385],[-113,-333],[-137,-228],[-194,-190],[-204,-97],[-281,32],[-123,-359],[4,-273],[-157,-252],[-14,-301],[69,-295],[451,-418],[-406,-1389],[-173,-243],[-403,-393],[4,-677]],[[48935,55715],[-262,-229],[-347,-217],[-305,-130],[-391,-418],[-241,-625],[-311,-576],[-413,-659],[-259,-468],[-356,-761],[-238,-332],[-201,-165],[-427,-208],[-160,-146],[106,-187],[-232,-330],[-329,-663],[-128,-102],[-217,-458],[-345,-453],[-68,98],[-169,-103]],[[85440,62725],[-111,312],[-600,362],[-239,212],[-252,486],[-191,99],[-299,322],[-177,132],[-562,-613]],[[97006,56150],[97,398],[175,371],[84,83],[93,298],[187,420],[-83,253],[-192,975],[-427,-32],[-359,-89],[-147,474],[63,248],[-130,117],[-79,-76],[-192,163],[-361,-55],[-623,428],[-209,253],[-5,303],[405,1016],[-41,512],[-86,128],[-448,-32],[-454,95],[-382,-36],[-567,16],[-493,-58],[-118,28],[-545,-60],[-189,29],[-336,-87],[-162,-121],[-382,-186],[-944,-264],[-847,305],[-287,175],[-329,-62],[-386,-157],[-255,3],[-199,-110],[-489,-38],[-170,118],[-260,-68],[-380,58],[-432,174]],[[83877,44385],[319,-12],[461,-81],[569,-217],[1035,-257],[647,77],[367,114],[368,-81],[673,-19],[243,32],[247,-235],[24,-296],[359,-231],[151,-43],[442,-353],[116,-161],[275,-118],[362,11],[661,192],[145,-165],[192,55],[57,214],[441,401],[139,46],[123,157],[317,110],[217,188],[154,213],[290,88],[275,316],[413,334],[256,334],[278,258],[458,563],[200,158],[760,441],[144,146],[1570,554],[534,205],[769,247],[1071,713],[-582,250],[-511,-313],[-195,5],[-203,-167],[-757,-59],[-594,-5],[-259,-67],[-272,28],[-362,-36],[-226,180],[-193,266],[-98,-2]],[[27875,37174],[-123,44],[-89,332],[-223,-77],[-173,-160],[-172,85],[-261,-222],[-344,-99],[-113,206],[-358,-191]],[[30370,25637],[-87,150],[118,145],[261,576],[170,206],[204,130],[112,158],[73,407],[-109,257],[-36,535],[214,169],[252,122],[-27,449],[-374,-195],[-245,-70],[-263,58],[-113,150],[-21,177],[94,91],[475,86],[473,307],[-289,1173],[-79,-42],[-137,184],[-280,534],[48,54],[-227,278],[-122,51],[-168,-136],[-118,172],[-138,-108],[-416,703],[-151,306],[-244,-136],[-301,506],[-78,56],[-291,422],[-106,26],[-295,571],[-403,-185],[-83,278],[-239,227],[-104,284],[-579,-670],[-143,202],[-61,236],[521,623],[863,859],[-339,632],[218,317],[75,212]],[[30218,25261],[152,376]],[[26019,37092],[-160,-74],[-597,-449],[-177,-56],[-378,-242],[-466,-190],[-49,-234],[-644,-366],[-505,-170],[-220,-523],[-103,-722],[201,-76],[69,-219],[327,-284],[-375,-713],[-167,-143],[-473,-257],[172,-363],[53,-494],[190,12],[335,-147],[132,8],[35,-485],[237,-335],[76,10],[216,-420],[194,-564],[98,-142],[124,-340],[189,236],[294,198],[61,-95],[276,211],[66,115],[259,-124],[123,78],[294,-165],[405,-765],[275,-301],[-16,-170],[129,-621],[134,119],[302,-437],[712,533],[312,188],[416,-694],[83,-218],[229,145],[76,-270],[130,-213],[323,213],[489,-339],[214,-183],[-16,-392],[-245,-60],[-27,-383],[272,-57],[61,-156],[234,-246]],[[14597,9807],[-75,113],[-299,977],[-106,-45],[-291,596],[63,12],[-346,330],[-161,317],[-180,144],[-1658,1083],[-482,668],[-226,279],[-157,332],[-118,438],[-418,-458],[-347,-326],[-174,296],[-194,495],[-217,-80],[-113,-147],[-443,172],[-117,174],[-599,249],[-471,147],[-142,-300],[-81,-311],[-120,240],[-269,265]],[[6856,15467],[-72,-165],[-320,-136],[-214,-224],[-83,-210],[-244,-379],[-308,-165],[-109,-521],[-182,-692],[10,-88],[-185,-381],[-280,-446],[-102,-403],[-91,-163],[-67,-714],[69,-361],[29,-386],[-65,-147],[-289,-127],[-630,146],[-177,-303],[-123,-782],[-93,-187],[-248,-274],[-185,-79],[-651,-538],[-512,-297],[-104,-144],[-369,-310],[-156,-79],[-439,-413],[-304,-168],[-315,-326],[-47,-175],[278,-728],[81,-286],[598,-367],[176,-15],[637,231],[293,-133],[112,-144],[307,-82],[199,64],[206,-32],[259,793],[1214,1593],[664,-3757],[416,-682],[-42,-1187],[396,-321],[52,-417],[118,-360],[234,220],[313,58],[190,254],[476,417],[475,108],[351,304],[247,62],[843,454],[-51,133],[341,205],[-92,234],[117,138],[81,-218],[122,139],[576,923],[464,306],[-73,159],[338,159],[1512,1244],[728,1025],[307,295],[132,312],[227,1352],[181,272],[-129,206],[88,608],[94,210],[541,228]],[[19600,18241],[-119,-5],[-29,-335],[180,-738],[72,-443],[-427,-241],[-286,-225],[-495,-473]],[[25059,23246],[-103,-60],[213,-248],[-120,-167],[115,-173],[-277,-409],[-236,-286],[-474,-349],[-17,70],[-228,-107],[9,-331],[220,-592],[-183,-111],[-434,-364],[48,-248],[92,-87],[118,64],[197,-391],[-148,-203],[-64,45],[-156,-360],[-217,231],[-65,277],[-309,-57],[-133,228],[-264,-81],[-658,42],[-139,-39],[26,-194],[83,42],[31,-316],[-295,168],[39,-266],[-91,-523],[-155,-44],[-5,408],[-280,-87],[13,-415],[-107,-66],[-168,291],[-290,57],[-19,-276],[-93,124],[-407,-29],[56,-166],[-251,-25],[-122,-100],[-51,113],[-160,5]],[[28800,21395],[-85,-19],[-404,306],[-247,-80],[-660,624],[-154,549],[-281,-168],[-23,504],[-338,-117],[-34,138],[-280,-120],[-677,-138],[-145,236],[346,581],[-89,117],[-159,-305],[-49,34],[-379,-415],[-83,124]],[[21532,10840],[200,1164],[1778,134],[1990,509],[961,1853],[307,1045],[348,1084],[268,1013],[1047,2383],[-85,330],[392,751],[62,289]],[[18496,15781],[132,-343],[-90,-81],[136,-350],[92,78],[153,-255],[17,-803],[104,23],[94,-318],[-383,-149],[-102,-154],[268,-322],[206,-439],[-188,-125],[126,-545],[153,-498],[80,-64],[198,49],[374,-57],[10,-494],[42,-168],[164,-4],[392,298],[159,49],[123,-81],[776,-188]],[[32256,40423],[232,124],[278,59]],[[27875,37174],[97,-30],[314,75],[128,-354],[842,846],[154,215],[-148,523],[378,142],[147,-311],[339,388],[135,-189],[174,242],[168,97],[247,470],[502,338],[228,262],[206,138],[470,397]],[[23662,41879],[-716,342],[-187,-137],[-142,-210],[-119,-320],[-230,-373],[-182,-226],[-334,-309],[-327,-20],[-7,-178],[117,-275],[-5,-487],[272,-347],[31,-154],[-142,-19],[-54,-182],[173,14],[156,-82],[50,-215],[202,-5],[39,123],[151,-8],[116,-295],[-70,-218],[-130,-73],[107,-290],[-225,-147],[168,-366],[369,159],[201,156],[1217,804],[1055,407],[202,181],[415,-1205],[97,-205],[89,-627]],[[31338,41571],[-284,-201],[-319,-17],[-350,49],[-171,-41],[-248,139],[-325,297],[-243,86],[-403,-181],[-308,-56],[-375,-198],[-412,-73],[-651,-484],[-342,-317],[-585,-315],[-213,129],[-378,0],[-227,125],[-175,227],[-49,294],[68,265],[-395,180],[-690,-21],[-527,-84],[-144,22],[38,120],[-94,131],[126,232]],[[32766,40606],[67,187],[-45,274],[-113,160],[-10,368],[-248,-23],[-187,135],[-255,-63],[-185,-152],[-259,-107],[-193,186]],[[21267,38783],[182,46],[107,308],[-215,93],[39,286],[-209,13],[-283,-248],[32,-389],[266,57],[81,-166]],[[36279,33021],[-245,-258],[-521,-350],[-297,521],[-319,619],[-110,-299],[-388,-457],[-382,-492],[77,-135],[-226,-264],[58,-94],[-644,-1055],[131,-794],[35,-462],[-3,-450],[53,-480],[-52,-669],[-83,-582]],[[43015,33284],[-562,-103],[-505,-62],[-161,25],[-790,-95],[-400,-116],[-133,-79],[-338,-74],[-228,-198],[-439,-140],[-506,-238],[-712,-519],[-139,-224],[-207,-141],[-124,36],[-184,339],[-132,105],[-211,-209],[-147,125],[-256,395],[-217,633],[-201,70],[-144,207]],[[33363,27320],[57,-853],[-51,-379],[313,1],[368,527],[99,25],[282,-541],[-17,-302],[237,-237],[-131,-215],[-301,-235],[371,-839],[1087,-2],[31,445],[117,265],[243,399],[266,363],[343,241],[198,-40],[221,-152],[174,-43],[343,46],[194,-160],[326,179],[195,41],[613,373],[285,89],[811,182],[327,-10],[360,-146],[145,0],[387,-137],[202,-128],[287,-101],[65,282],[498,106],[459,217],[553,342],[349,308],[311,-33],[-352,976],[-560,814],[240,99],[118,162],[-41,205],[-226,180],[-223,31],[-605,-132],[-157,-5],[39,300],[11,756],[457,135],[0,190],[153,285],[208,152],[7,290],[-244,-164],[-221,762],[56,170],[230,363],[-8,168],[187,271],[-34,78]],[[36423,38537],[-36,-191],[404,35],[48,-242],[333,-3],[18,-54],[-269,-326],[299,20],[267,-151],[-253,-153],[-427,-359],[-89,-185],[4,-333],[85,-26],[30,-235],[-105,-373],[360,-353],[49,78],[130,-144],[-86,-338],[-238,-706],[-228,-429],[-370,-584],[-133,-262],[63,-202]],[[39708,39840],[-547,-472],[-441,-261],[-207,340],[-182,480],[-112,-48],[-1192,-990],[-399,-173],[-205,-179]],[[43015,33284],[239,233],[302,140],[409,304],[216,9],[460,160],[219,195],[455,218],[479,336],[-29,250],[38,383],[-103,797],[-12,445],[86,515],[94,122],[148,-144],[1,240],[-131,309],[-37,270],[-354,-52],[-176,157],[-65,737],[528,494],[117,39],[-173,225],[-434,306],[-221,105]],[[30370,25637],[246,298],[254,126],[343,41],[73,82],[546,104],[787,515],[744,517]],[[32766,40606],[301,118],[66,-57],[196,-638],[-318,-316],[-273,223],[-62,133],[-269,-128],[-151,482]],[[33512,45873],[112,-349],[-97,-337],[-149,-315],[-336,-522],[-80,-42],[-305,-899],[-181,43],[-300,-79],[-60,-399],[28,-144],[-124,-200],[-300,-320],[-231,-183],[-151,-556]],[[35908,45851],[-255,134],[-685,-88],[-1228,108],[-228,-132]],[[36423,38537],[-271,788],[-386,-246],[225,-617],[-242,-185],[96,-383],[-610,-465],[56,-157],[-182,-112],[-258,481],[-302,-152],[-535,-109],[-7,-102],[-253,-173],[-359,-134],[-127,71],[-179,247],[-35,157],[451,329],[610,365],[204,230],[-479,562],[47,179],[-40,224],[310,409],[-353,508],[90,548],[-86,196],[64,145],[430,292],[231,214],[765,466],[169,291],[254,-51],[87,615],[70,80],[241,3],[438,89],[-63,575],[10,404],[-55,342],[-62,-39],[-49,391],[-306,91],[50,308],[-174,639]],[[15912,24439],[116,-84],[187,44],[235,-63],[390,-221],[434,-53],[315,151],[62,-240],[131,-188],[114,189],[399,355],[331,225],[122,-213],[-23,-320],[291,-561],[-88,-104],[112,-161],[-265,-400],[-27,-382],[60,-259],[-48,-71],[66,-264],[53,70],[146,-251],[-59,-162],[-226,-250],[121,-401],[309,161],[248,-445],[-15,-385],[81,-178],[-167,-172],[122,-217],[366,280],[19,-158],[-235,-131],[-155,-201],[88,-120],[-58,-119],[70,-282],[66,-617]],[[25059,23246],[-1,121],[-166,296],[-221,-129],[-90,227],[-216,270],[-195,586],[-246,-120],[-150,377],[-5,177],[-197,310],[87,66],[-88,182],[-140,-96],[-216,287],[-158,-77],[-138,432],[-193,421],[102,40],[-75,285],[-285,-106],[-61,166],[-361,135],[-18,105],[-155,-128],[-366,105],[-47,-32],[-127,354],[-314,3],[-194,691],[-60,-75],[-236,408],[-195,249],[34,63],[-385,344],[-90,-34],[-12,-245],[-106,-123],[-109,47],[-157,-163],[-314,157],[-403,-207],[-150,-148],[-207,51],[-101,187],[-307,-451],[34,-82],[-172,-231],[-3,-410],[-102,-264],[-142,-643],[-48,-478],[-348,-316],[-236,-299],[-332,-228],[-480,-203],[-133,-413],[-153,-248]],[[15556,10363],[128,-283],[-65,-183],[386,-517],[-288,-316],[73,-163],[76,84],[232,-521],[598,388],[88,-98],[107,109],[666,-206],[418,19],[132,-37],[225,-411],[228,-534],[446,-872],[275,-68],[121,-162],[125,42],[343,369],[329,268],[161,262],[-68,127],[314,590],[272,719],[-88,117],[311,651],[149,261],[206,214],[76,628]],[[18496,15781],[-438,-437],[-466,-285],[-355,-282],[-495,-303],[-473,-130],[-619,-609],[-178,-135],[110,-349],[320,-456],[227,-432],[114,-299],[115,-594],[-17,-225],[-108,-262],[19,-161],[-699,-380],[3,-79]],[[14597,9807],[959,556]],[[14307,23747],[-142,-585],[-130,-287],[-260,-244],[-840,6],[-279,-150],[-422,-407],[-99,-184],[-38,-278],[48,-334],[-105,-303],[-114,-178],[-265,-564],[-386,-441],[-227,-69],[-446,-319],[-462,-241],[-25,119],[-371,-127],[-290,-609],[-136,-399],[-802,-720],[-206,-354],[-214,-274],[-342,-338],[-292,-172],[-258,-247],[-348,-581]],[[15912,24439],[-571,-172],[-111,199],[-456,-315],[133,-168],[135,-291],[-277,61],[-458,-6]],[[28800,21395],[63,98],[393,252],[407,173],[301,218],[165,212],[315,303],[-91,234],[-69,719],[-160,671],[-5,253],[173,222],[-113,242],[39,269]],[[23427,42480],[-389,158],[-152,-8],[-389,-550],[-208,-519],[-227,-340],[-274,-251],[-234,-19],[-470,290],[-408,-1],[-69,-84],[-591,-273],[-257,16],[-295,278],[-373,-8],[-92,-384],[45,-410],[-148,-436],[-214,-190],[-174,10],[-427,338],[-124,44],[-815,-341],[-379,-5],[-414,244],[-482,-4],[-355,-71],[-355,-177],[-175,-217],[-424,-677],[-426,-415],[-51,-156],[64,-371],[231,-422],[211,-290],[158,-401],[-59,-474],[137,-439],[79,-121],[246,-665],[211,-736],[281,-687],[-1,-247],[-225,-578],[-41,-297],[213,-1068],[-85,-717],[-130,-394],[-86,-498],[-401,-616],[108,-1130],[188,-341],[445,-488],[261,-645],[207,-273],[46,-172],[-98,-240],[-178,-131],[-300,-128],[-461,-672],[-740,-405],[-59,-155],[49,-299],[-45,-475]],[[23662,41879],[43,215],[178,100],[-217,21],[-239,265]],[[43642,48583],[-57,130],[-162,-35],[-291,35],[-55,196],[171,-23],[402,57],[223,300],[-58,273],[-118,140],[158,147],[173,53],[57,169],[-231,42],[-172,-160],[-209,-38],[-99,995],[-198,617],[-110,-71],[-497,-23],[-340,150],[-338,371],[-219,132],[-425,139],[-114,-69],[-80,-193],[-18,-431],[98,-589],[-65,-436],[-241,-230],[-128,13],[-486,-82],[-272,-106],[-626,-397],[-765,-349],[-333,-216],[-365,-326],[-492,-95],[-319,-204],[-63,-124],[-79,-528],[-87,-202],[111,-161],[247,-27],[136,84],[305,-197],[96,-390],[213,-193],[-107,-30],[-492,17],[-606,-107],[-391,-174],[-236,-54],[-94,-140],[-86,-392]],[[27183,50153],[-211,-158],[-330,-86],[15,-147],[-640,-212],[-777,-132],[-247,-69],[-354,-14],[-477,-161],[-393,-70],[-50,-836],[-51,-357],[158,22],[356,-56],[182,-586],[145,-342],[111,-638],[-60,-385],[-141,-547],[-190,-606],[-191,-99],[-148,-226],[-45,-216],[-28,-502],[-104,-785],[-286,-465]],[[33512,45873],[-105,223],[-71,412],[-176,-75],[-642,-88],[-235,118],[320,181],[-196,648],[-100,247],[-96,-45],[-2,246],[-146,-39],[-80,-345],[-174,474],[-294,355],[-216,-108],[-125,145],[-48,-212],[-214,65],[-21,-178],[-800,-999],[-346,-27],[-115,247],[-107,14],[-89,211],[50,204],[-321,114],[-476,-78],[-230,253],[150,380],[-15,345],[-203,739],[-333,41],[-589,124],[-268,330],[-16,358]],[[39559,83101],[-444,-270],[-276,90],[-151,-182],[-478,-337],[-126,-182],[-659,-424],[-446,-813],[-474,-473],[-142,-205]],[[43670,81424],[-205,397],[-247,37],[-211,-39],[14,-75],[-234,-38],[-17,218],[-1001,-241],[-455,-64],[-497,-133],[-294,-30],[-257,1126],[-35,-32],[-344,218],[-328,333]],[[43709,77454],[-208,878],[94,237],[-112,828],[-171,1010],[187,77],[-57,396],[228,544]],[[41328,73511],[58,55],[898,1395],[193,800],[310,504],[188,247],[133,318],[138,185],[122,311],[183,165],[158,-37]],[[37277,74760],[354,-41],[497,35],[407,83],[-115,-238],[37,-195],[708,-44],[269,164],[551,65],[38,-554],[300,-123],[211,-664],[668,517],[126,-254]],[[36363,80305],[66,-894],[23,-1084],[298,-772],[330,-1007],[197,-1788]],[[22611,89478],[219,704],[1,335],[99,332],[126,181],[100,449],[707,119],[450,32],[263,121],[247,37],[-99,77],[-118,474],[30,471],[144,290],[417,404],[6,438],[125,536],[144,468],[52,332],[385,110],[269,28],[150,-71],[310,429],[230,462],[236,378],[176,433],[195,264],[222,705]],[[27697,98016],[-38,479],[-339,-3],[-465,353],[-241,318],[-200,-61],[-170,306],[-203,538],[-474,53],[-189,-18],[-344,-197],[-130,1],[-1388,-645],[-416,-175],[-466,-286],[-6,-184],[-622,-496],[-699,-409],[-355,-277],[-315,-425],[-422,347],[-46,-253],[523,-433],[-94,-138],[162,-401],[115,-550],[118,-397],[-23,-1080],[8,-584],[-303,-1323],[193,-398],[81,-311],[-21,-207],[586,-417],[86,-262],[-252,-551],[-74,-327],[119,-343],[839,172],[379,46]],[[26230,79402],[-179,189],[-348,3628]],[[25866,79076],[364,326]],[[22556,76290],[55,1063],[258,287],[390,187],[546,422],[989,420],[1055,464],[17,-57]],[[19518,75487],[619,-12],[355,-69],[346,12],[506,107],[232,414],[414,232],[42,-251],[434,155],[-1,175],[91,40]],[[17474,80633],[328,-577],[301,-416],[79,-296],[158,60],[305,-772],[107,-422],[218,-522],[171,-295],[186,-476],[191,-1430]],[[22716,87983],[-246,-238],[-227,-345],[49,-32],[-102,-935],[540,-132],[102,-514],[-427,-474],[-453,-796],[-381,-259],[-409,-207],[-331,-59],[-519,125],[-426,299],[-796,-409],[-189,-4],[-66,-161],[-435,-15],[-214,-941],[-124,-733],[-229,-997],[-359,-523]],[[25703,83219],[113,262],[298,116],[-456,1561],[-100,193],[-773,1215],[-236,342],[-531,315],[-26,179],[-442,256],[-332,297],[-142,-33],[-360,61]],[[32146,88708],[-9,-622],[250,-690],[390,-837],[156,-528],[-74,-214],[-201,-339],[-615,-504],[-9,-420]],[[38792,88457],[-83,3],[-199,283],[-164,120],[-100,-95],[-567,333],[-31,-149],[-409,181],[-319,244],[-31,-131],[-139,-37],[-550,213],[-207,40],[-625,-41],[-208,84],[-1324,-183],[-16,81],[-409,-291],[-227,-62],[-579,-381],[-459,39]],[[39559,83101],[-206,1050],[46,418],[122,648],[166,397],[-89,193],[-52,1106],[-95,855],[141,223],[-864,-226],[-17,108],[173,549],[-92,35]],[[32115,81945],[182,5],[497,-452],[248,-55],[269,7],[235,155],[521,114],[392,-277],[130,-207],[157,-567],[108,-197],[445,-277],[535,103],[144,-99],[71,-209],[108,54],[206,262]],[[32034,84554],[178,-823],[22,-962],[-160,-532],[41,-292]],[[45483,65399],[294,266],[921,328],[290,216]],[[41328,73511],[222,-454],[384,-529],[483,-473],[-223,-59],[131,-187],[-118,-40],[690,-1360],[72,38],[134,-224],[401,-207],[141,-426],[-57,-38],[318,-1187],[262,-462],[40,-179],[123,-41],[35,-225],[104,-59],[254,-504],[605,-1100],[154,-396]],[[46988,66209],[515,424],[714,691],[128,78],[91,-75],[-239,613],[-219,961],[141,97],[16,130],[-121,557],[-116,-80],[-39,208],[-121,-48],[-41,198],[121,40],[207,827],[-184,364],[-207,718],[-78,464],[-430,1628],[-61,-22],[-145,495],[-182,505],[-104,-78],[-301,779],[-412,615],[-819,493],[-307,382],[-306,159],[-780,122]],[[26230,79402],[263,-411],[61,-301],[-91,-378],[144,130],[424,-323],[33,74],[373,15],[255,-344],[288,-41],[209,117],[289,405],[546,338],[494,420],[769,161],[92,-157],[30,-232],[288,-91],[28,238],[229,163],[104,-258],[214,324],[150,146],[-86,164],[201,365],[-67,159],[164,198],[377,309],[-336,307],[-116,208],[-2,263],[90,219],[188,207],[280,149]],[[32034,84554],[-469,-259],[-131,-151],[-379,-121],[-2,-111],[-177,46],[-134,-188],[54,-116],[-153,-33],[22,-144],[-170,-12],[-36,192],[-544,-100],[-576,148],[-355,28],[-420,-49],[-387,123],[-244,-182],[-1067,-671],[-142,-164],[-208,225],[-422,-119],[-133,233],[-258,90]],[[37277,74760],[-361,-51],[-1079,-836],[-337,-629]],[[34405,61721],[374,-130],[881,305],[949,859],[372,76],[67,246],[-284,-5],[-11,237],[409,106],[131,127],[213,-166],[-81,-166],[231,4],[235,138],[211,-83],[377,99],[-12,-138],[244,-277],[277,382],[26,-149],[227,285],[40,209],[-53,186],[217,561],[63,-257],[117,21],[27,-434],[195,110],[283,-283],[283,298],[462,199],[288,-39],[725,35],[325,450],[395,-239],[587,-124],[393,94],[517,232],[244,-87],[172,87],[289,311],[233,157],[440,441]],[[35500,73244],[89,-384],[119,-259],[-39,-75],[104,-220],[-137,-434],[144,-22],[-24,-189],[80,-286],[25,-448],[-53,-388],[70,-131],[-343,-260],[34,-80],[-163,-319],[-39,-331],[-210,-623],[-8,-356],[52,-140],[419,172],[25,-99],[-167,-148],[-123,-531],[-112,24],[27,-518],[88,-311],[-13,-594],[46,-457],[132,-281],[228,-177],[105,-296],[-31,-192],[-314,-383],[-143,-228],[-62,-228],[9,-286],[-54,-317],[32,-117],[-267,-463],[-430,-827],[-191,-321]],[[26532,68966],[241,3],[447,309],[223,302],[336,258],[-9,67],[737,292],[828,78],[-15,153],[643,123],[366,129]],[[22556,76290],[239,-670],[204,-166],[-72,-89],[234,-182],[422,-486],[234,-336],[229,65],[170,-120],[-129,-58],[249,-372],[142,-108],[274,-521],[190,-297],[-70,-80],[157,-403],[-5,-151],[174,-276],[206,-473],[103,-94],[98,-520],[160,-380],[312,-311],[285,-1],[143,-149],[-20,-389],[-108,-123],[-28,-277],[60,-346],[123,-11]],[[30329,70680],[18,340],[72,234],[-208,-162],[-45,213],[-409,992],[-181,320],[-99,347],[-192,484],[-40,242],[-282,429],[-168,387],[6,288],[158,217],[-380,408],[-243,351],[-279,28],[-982,3],[-317,802],[-215,665],[-383,917],[-294,891]],[[17474,80633],[-854,-554],[-361,416],[-709,-244],[-387,-104],[-371,-38],[-344,19],[-225,-166],[-30,-625],[42,-221],[106,-2751],[32,-1389],[-98,-884],[-2,-278],[-344,-1556]],[[16731,72005],[463,45],[185,-47],[141,65],[-62,338],[240,155],[-62,87],[269,962],[263,251],[307,124],[0,116],[275,-145],[96,731],[111,-17],[561,817]],[[13929,72258],[401,57],[34,-358],[335,-62],[-35,-114],[886,153],[47,-225],[274,-420],[766,981],[94,-265]],[[27174,61377],[911,399],[542,47],[738,105],[253,-9],[131,-144],[512,61],[132,121],[369,207],[201,67],[239,164],[376,91],[-15,-311],[277,-66],[172,-141],[584,-29],[399,68],[-16,-118],[306,-225],[235,48],[291,-12],[294,-114],[300,135]],[[24126,62783],[129,-412],[156,109],[187,308],[363,-85],[14,-359],[255,-291],[597,-138],[686,-215],[161,100],[276,61],[216,-11],[8,-473]],[[26532,68966],[-45,-112],[-257,-91],[-309,122],[-505,-363],[-252,-507],[-83,-410],[-53,-906],[-8,-890],[-155,-943],[-71,-9],[-104,-776],[-284,-139],[-140,-265],[-106,-433],[20,-210],[-54,-251]],[[35500,73244],[-425,-98],[-509,-346],[-616,-227],[-405,-49],[-439,29],[-200,59],[-22,-196],[40,-392],[-625,-391],[-15,110],[-177,-133],[46,-163],[-384,-125],[-76,-326],[-219,-364],[-41,468],[-286,-542],[-372,-40],[-446,162]],[[9272,65636],[54,-209],[321,106],[510,-221],[22,-375],[305,130],[208,187],[480,116],[240,-67],[-33,132],[387,-29],[96,-391],[373,2],[211,-108],[392,-30],[493,103],[245,102],[463,42],[211,-41],[89,-772],[-32,-239],[90,-361],[-35,-329],[76,-421],[130,-256],[106,-62],[74,-354],[124,262],[97,-56],[444,298],[235,28],[172,112],[280,90],[40,-318],[6,-500],[148,-20],[-56,629],[-228,633],[-215,294],[-367,354],[-295,735],[-22,141],[209,624],[21,493],[-17,399],[-99,68],[12,529],[39,263],[150,413],[144,-62],[113,215],[109,22],[349,241],[103,525],[-80,104],[-29,582],[87,482],[357,445],[-78,639],[-238,356],[487,624],[-19,70]],[[13929,72258],[-585,-83],[-816,-17],[-161,36],[-426,-4],[-270,-41],[-215,-154],[-126,441],[-352,-360],[-547,-212],[246,-150],[237,-52],[143,-198],[-65,-144],[-74,-540],[-175,-459],[-11,-559],[-296,-41],[-421,-130],[-143,-122],[62,-86],[95,-391],[156,-184],[-78,-610],[51,-266],[338,-384],[-52,-350],[-202,-534],[-262,-319],[-692,-469],[-16,-240]],[[39024,88976],[-92,-55],[-140,-464]],[[47296,88478],[-424,-177],[-548,-181],[-306,1],[-541,-423],[-118,225],[-169,73],[-510,-179],[-144,24],[-34,-253],[-754,-207],[-80,187],[-173,-124],[-285,38],[-667,-100],[-152,-63],[-315,177],[-284,-38],[1,201],[-277,-144],[-481,-89],[-317,-99],[-356,672],[-294,256],[-284,306],[-370,233],[-390,182]],[[46124,82479],[-38,216],[303,606],[134,450],[49,371],[157,381],[68,415],[174,637],[80,471],[212,852],[-114,108],[-19,257],[100,68],[100,234],[-18,259],[50,392],[-66,282]],[[43670,81424],[151,455],[286,146],[298,17],[651,-116],[379,168],[-5,106],[341,91],[353,188]],[[32941,95342],[-317,442],[-64,745],[-1276,633],[-288,230],[-360,9],[-339,-112],[-456,33],[-428,274],[-505,542],[-158,135],[-188,-82],[-865,-175]],[[32146,88708],[12,239],[-66,489],[-338,762],[230,180],[212,47],[157,235],[-43,76],[303,279],[-34,59],[232,231],[-46,857],[50,357],[55,1260],[76,554],[-5,1009]],[[22611,89478],[-98,-631],[203,-864]],[[27174,61377],[30,-281],[-1,-662],[62,-373],[405,104],[68,70],[679,78],[190,-120],[332,-352],[229,-80],[192,-257],[16,-694],[80,-310],[177,-365],[-52,-225],[7,-291],[115,-541],[43,-434],[-227,-186],[-90,-207],[-91,-629],[672,-61],[161,-75],[736,-767],[166,-128],[-365,-1234],[-204,-126],[-395,-123],[-158,-161],[119,-192],[-319,-254],[100,-359],[-117,-59],[250,-147],[325,-85],[-758,-1094],[-823,-1132],[-329,-11],[-863,427],[-353,112]],[[51850,62726],[-181,442],[-229,389],[-95,-1],[-61,173],[-470,-26],[-294,-245],[-579,238],[-308,183],[-230,384],[-229,-214],[-181,-14],[-315,-227],[-164,-193],[-258,74],[-123,646],[-4,797],[-186,-204],[-182,7],[-371,-264],[-84,483],[-80,161],[-60,426],[-178,468]],[[9272,65636],[-174,31],[-428,-79],[-562,-30],[-229,-140],[97,-513],[-315,-232],[-705,-720],[-439,-588],[-248,-433],[-4,-190],[82,-878],[98,-472],[-161,-495],[-73,-751],[-107,-512],[-136,-260],[-153,-156],[-156,-548],[5,-706],[-54,-458],[32,-308],[515,-52],[305,184],[247,59],[43,187],[596,458],[2,76],[214,101],[144,-7],[102,127],[-28,256],[141,312],[325,-62],[228,-212],[326,484],[248,24],[433,-193],[248,-53],[437,-202],[489,-109],[74,-62],[166,-373],[351,-225],[565,32],[54,-73],[732,564],[208,192],[230,62],[90,96],[277,-256],[621,74],[444,-49],[504,449],[276,14],[403,105],[114,72],[39,-263],[212,79],[353,-66],[301,100],[335,-52],[207,199],[229,79],[41,-155],[199,-145],[306,101],[338,229],[8,168],[557,-253],[135,239],[219,99],[743,539],[254,109],[444,34],[953,-170],[283,107],[337,249],[437,457],[342,294],[421,263],[274,663],[393,681]],[[56545,76230],[125,319],[-12,340],[-97,383],[38,510],[-272,364],[-664,202],[-206,584],[136,457],[52,309],[-452,1065],[-299,446],[-612,361],[-478,39],[-343,-81],[-289,-274],[-403,-195],[-112,-96],[-334,-89],[-400,-209],[-154,-187],[-200,-41],[-389,-282],[-150,206],[-795,-107],[-566,70],[-94,563],[-173,284],[-185,169],[-688,311],[-946,485],[-417,156],[-292,175],[-246,53],[-504,-41]],[[39024,88976],[136,454],[336,1711],[137,898],[48,104],[256,-86],[488,-46],[54,481],[-249,414],[-142,386],[-186,-105],[-223,697],[-253,-129],[-126,494],[-94,9],[-77,294],[-112,178],[-238,122],[98,158],[-135,83],[-192,697],[-48,329],[-74,6],[-18,249],[-193,-4],[-77,496],[-14,396]],[[38126,97262],[-995,-97],[-339,-94],[-355,-16],[-433,245],[-371,77],[-389,-203],[-368,-397],[-532,-477],[-500,-531],[-444,-282],[-459,-145]],[[47296,88478],[75,54],[-11,366],[-74,173],[29,171],[-170,213],[8,112],[186,345],[241,622],[91,417],[108,156],[129,499],[244,552],[242,1041],[75,451],[353,722],[128,309],[77,340],[-8,325],[270,136],[185,-26],[185,125],[427,177],[615,398],[-126,349],[-76,6],[-13,325],[-63,135],[-550,-186],[-233,-24],[-341,-183],[-447,-168],[-218,-132],[-416,-172],[-400,-88],[-884,-130],[-376,-178],[-363,-77],[-426,-22],[-184,202],[-526,-26],[-408,204],[-533,688],[-412,899],[-285,287],[-711,526],[-841,746],[-487,187],[-270,13],[-480,135],[-312,265],[-201,-366],[-410,-446],[-108,-163],[-515,-577],[-478,-583],[-482,-340]]],"transform":{"scale":[0.006642020335543532,-0.004800048000480005],"translate":[147.90230423299118,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/lu.json b/src/onegov/election_day/static/mapdata/2025/lu.json new file mode 100644 index 0000000000..34ce44fc7d --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/lu.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":1001,"properties":{"id":1001,"name":"Doppleschwand"},"arcs":[[-1,-2,-3,-4]]},{"type":"MultiPolygon","id":1002,"properties":{"id":1002,"name":"Entlebuch"},"arcs":[[[-5,1,-6,-7,-8,-9]],[[-10,-11,-12]]]},{"type":"Polygon","id":1004,"properties":{"id":1004,"name":"Flühli"},"arcs":[[-13,-14,-15,-16]]},{"type":"Polygon","id":1005,"properties":{"id":1005,"name":"Hasle (LU)"},"arcs":[[-17,11,-18,2,4,-19,14]]},{"type":"Polygon","id":1007,"properties":{"id":1007,"name":"Romoos"},"arcs":[[3,17,10,-20,-21,-22,-23,-24,-25]]},{"type":"Polygon","id":1008,"properties":{"id":1008,"name":"Schüpfheim"},"arcs":[[19,9,16,13,-26]]},{"type":"Polygon","id":1009,"properties":{"id":1009,"name":"Werthenstein"},"arcs":[[-27,6,-28,-29]]},{"type":"Polygon","id":1010,"properties":{"id":1010,"name":"Escholzmatt-Marbach"},"arcs":[[-30,20,25,12]]},{"type":"Polygon","id":1021,"properties":{"id":1021,"name":"Aesch (LU)"},"arcs":[[-31,-32,-33,-34]]},{"type":"Polygon","id":1023,"properties":{"id":1023,"name":"Ballwil"},"arcs":[[-35,-36,-37,-38,-39]]},{"type":"Polygon","id":1024,"properties":{"id":1024,"name":"Emmen"},"arcs":[[-40,-41,-42,-43,-44,-45]]},{"type":"Polygon","id":1025,"properties":{"id":1025,"name":"Ermensee"},"arcs":[[-46,-47,-48]]},{"type":"Polygon","id":1026,"properties":{"id":1026,"name":"Eschenbach (LU)"},"arcs":[[-49,-50,43,-51,-52,-53,37]]},{"type":"Polygon","id":1030,"properties":{"id":1030,"name":"Hitzkirch"},"arcs":[[-54,-55,47,-56,32,-57,-58]]},{"type":"Polygon","id":1031,"properties":{"id":1031,"name":"Hochdorf"},"arcs":[[38,52,-59,-60,-61]]},{"type":"Polygon","id":1032,"properties":{"id":1032,"name":"Hohenrain"},"arcs":[[-62,34,60,-63,53]]},{"type":"Polygon","id":1033,"properties":{"id":1033,"name":"Inwil"},"arcs":[[-64,48,36,-65,-66,-67,-68]]},{"type":"Polygon","id":1037,"properties":{"id":1037,"name":"Rain"},"arcs":[[-69,-70,58,51,-71,-72]]},{"type":"Polygon","id":1039,"properties":{"id":1039,"name":"Römerswil"},"arcs":[[59,69,-73,-74,45,54,62]]},{"type":"Polygon","id":1040,"properties":{"id":1040,"name":"Rothenburg"},"arcs":[[-75,70,50,42]]},{"type":"Polygon","id":1041,"properties":{"id":1041,"name":"Schongau"},"arcs":[[56,31,-76]]},{"type":"Polygon","id":1051,"properties":{"id":1051,"name":"Adligenswil"},"arcs":[[-77,-78,-79,-80,-81,-82]]},{"type":"Polygon","id":1052,"properties":{"id":1052,"name":"Buchrain"},"arcs":[[-83,-84,-85,44,49,63]]},{"type":"Polygon","id":1053,"properties":{"id":1053,"name":"Dierikon"},"arcs":[[83,-86,-87,79,-88]]},{"type":"Polygon","id":1054,"properties":{"id":1054,"name":"Ebikon"},"arcs":[[39,84,87,78,-89]]},{"type":"Polygon","id":1055,"properties":{"id":1055,"name":"Gisikon"},"arcs":[[-90,66]]},{"type":"Polygon","id":1056,"properties":{"id":1056,"name":"Greppen"},"arcs":[[-91,-92,-93]]},{"type":"Polygon","id":1058,"properties":{"id":1058,"name":"Horw"},"arcs":[[-94,-95,-96,-97]]},{"type":"Polygon","id":1059,"properties":{"id":1059,"name":"Kriens"},"arcs":[[-98,-99,-100,93,-101]]},{"type":"MultiPolygon","id":1061,"properties":{"id":1061,"name":"Luzern"},"arcs":[[[-102,40,88,77,-103,94,99,-104]],[[-105,-106]]]},{"type":"Polygon","id":1062,"properties":{"id":1062,"name":"Malters"},"arcs":[[-107,26,-108,-109,103,98]]},{"type":"Polygon","id":1063,"properties":{"id":1063,"name":"Meggen"},"arcs":[[-110,92,-111,95,102,76]]},{"type":"Polygon","id":1064,"properties":{"id":1064,"name":"Meierskappel"},"arcs":[[-112,-113,-114]]},{"type":"Polygon","id":1065,"properties":{"id":1065,"name":"Root"},"arcs":[[-115,112,-116,85,82,67,89,65]]},{"type":"Polygon","id":1066,"properties":{"id":1066,"name":"Schwarzenberg"},"arcs":[[-117,7,106,97]]},{"type":"Polygon","id":1067,"properties":{"id":1067,"name":"Udligenswil"},"arcs":[[-118,80,86,115,111]]},{"type":"Polygon","id":1068,"properties":{"id":1068,"name":"Vitznau"},"arcs":[[-119,-120]]},{"type":"Polygon","id":1069,"properties":{"id":1069,"name":"Weggis"},"arcs":[[-121,104,-122,110,91,-123,118]]},{"type":"Polygon","id":1081,"properties":{"id":1081,"name":"Beromünster"},"arcs":[[-124,-125,-126,-127,-128,33,55,46,73,-129,-130]]},{"type":"Polygon","id":1082,"properties":{"id":1082,"name":"Büron"},"arcs":[[-131,-132,-133,-134]]},{"type":"Polygon","id":1083,"properties":{"id":1083,"name":"Buttisholz"},"arcs":[[-135,-136,-137,-138,-139]]},{"type":"Polygon","id":1084,"properties":{"id":1084,"name":"Eich"},"arcs":[[123,-140,-141,-142,-143]]},{"type":"Polygon","id":1085,"properties":{"id":1085,"name":"Geuensee"},"arcs":[[133,-144,-145,125,-146,-147,-148]]},{"type":"Polygon","id":1086,"properties":{"id":1086,"name":"Grosswangen"},"arcs":[[136,-149,-150,-151,-152,-153]]},{"type":"Polygon","id":1088,"properties":{"id":1088,"name":"Hildisrieden"},"arcs":[[-154,-155,128,72,68]]},{"type":"Polygon","id":1089,"properties":{"id":1089,"name":"Knutwil"},"arcs":[[147,-156,-157,-158,-159,130]]},{"type":"Polygon","id":1091,"properties":{"id":1091,"name":"Mauensee"},"arcs":[[-160,-161,151,-162,-163,-164,156]]},{"type":"Polygon","id":1093,"properties":{"id":1093,"name":"Neuenkirch"},"arcs":[[-165,-166,153,71,74,41,101,108,-167]]},{"type":"Polygon","id":1094,"properties":{"id":1094,"name":"Nottwil"},"arcs":[[-168,138,-169,140,-170,164]]},{"type":"Polygon","id":1095,"properties":{"id":1095,"name":"Oberkirch"},"arcs":[[152,160,-171,-172,141,168,137]]},{"type":"Polygon","id":1097,"properties":{"id":1097,"name":"Rickenbach (LU)"},"arcs":[[144,-173,-174,126]]},{"type":"Polygon","id":1098,"properties":{"id":1098,"name":"Ruswil"},"arcs":[[166,107,28,-175,-176,134,167]]},{"type":"Polygon","id":1099,"properties":{"id":1099,"name":"Schenkon"},"arcs":[[-177,145,124,142,171]]},{"type":"Polygon","id":1100,"properties":{"id":1100,"name":"Schlierbach"},"arcs":[[-178,-179,172,143,132]]},{"type":"Polygon","id":1102,"properties":{"id":1102,"name":"Sempach"},"arcs":[[169,139,129,154,165]]},{"type":"Polygon","id":1103,"properties":{"id":1103,"name":"Sursee"},"arcs":[[155,146,176,170,159]]},{"type":"Polygon","id":1104,"properties":{"id":1104,"name":"Triengen"},"arcs":[[-180,-181,177,131,158,-182]]},{"type":"Polygon","id":1107,"properties":{"id":1107,"name":"Wolhusen"},"arcs":[[24,-183,174,27,5,0]]},{"type":"Polygon","id":1121,"properties":{"id":1121,"name":"Alberswil"},"arcs":[[-184,-185,-186]]},{"type":"Polygon","id":1122,"properties":{"id":1122,"name":"Altbüron"},"arcs":[[-187,-188,-189,-190,-191,-192]]},{"type":"MultiPolygon","id":1123,"properties":{"id":1123,"name":"Altishofen"},"arcs":[[[-193,-194,-195,-196,-197,-198,-199,-200,186]],[[-201,-202,-203,-204]]]},{"type":"Polygon","id":1125,"properties":{"id":1125,"name":"Dagmersellen"},"arcs":[[-205,-206,194,-207,181,157,163,-208]]},{"type":"Polygon","id":1127,"properties":{"id":1127,"name":"Egolzwil"},"arcs":[[-209,-210,-211,204]]},{"type":"Polygon","id":1128,"properties":{"id":1128,"name":"Ettiswil"},"arcs":[[185,-212,-213,161,150,-214]]},{"type":"Polygon","id":1129,"properties":{"id":1129,"name":"Fischbach"},"arcs":[[-215,198,-216,201,-217,-218,-219]]},{"type":"MultiPolygon","id":1131,"properties":{"id":1131,"name":"Grossdietwil"},"arcs":[[[-220,187,199,214]],[[191,-221,-222,-223,192]],[[197,-224,202,215]]]},{"type":"Polygon","id":1132,"properties":{"id":1132,"name":"Hergiswil bei Willisau"},"arcs":[[-225,-226,-227,-228,22]]},{"type":"Polygon","id":1135,"properties":{"id":1135,"name":"Luthern"},"arcs":[[-229,-230,225,-231]]},{"type":"Polygon","id":1136,"properties":{"id":1136,"name":"Menznau"},"arcs":[[182,23,227,-232,148,135,175]]},{"type":"Polygon","id":1137,"properties":{"id":1137,"name":"Nebikon"},"arcs":[[205,210,-233,195]]},{"type":"Polygon","id":1139,"properties":{"id":1139,"name":"Pfaffnau"},"arcs":[[-234,221,-235,189,-236]]},{"type":"Polygon","id":1140,"properties":{"id":1140,"name":"Reiden"},"arcs":[[-237,-238,179,206,193,222,233,-239]]},{"type":"Polygon","id":1142,"properties":{"id":1142,"name":"Roggliswil"},"arcs":[[234,220,190]]},{"type":"Polygon","id":1143,"properties":{"id":1143,"name":"Schötz"},"arcs":[[203,223,196,232,209,-240,211,184,-241,-242]]},{"type":"Polygon","id":1145,"properties":{"id":1145,"name":"Ufhusen"},"arcs":[[217,-243,-244,228,-245]]},{"type":"Polygon","id":1146,"properties":{"id":1146,"name":"Wauwil"},"arcs":[[207,162,212,239,208]]},{"type":"Polygon","id":1147,"properties":{"id":1147,"name":"Wikon"},"arcs":[[-246,236]]},{"type":"Polygon","id":1150,"properties":{"id":1150,"name":"Zell (LU)"},"arcs":[[241,-247,242,216,200]]},{"type":"Polygon","id":1151,"properties":{"id":1151,"name":"Willisau"},"arcs":[[213,149,231,226,229,243,246,240,183]]}]}},"arcs":[[[34221,50162],[-471,-74],[-297,-219],[-68,-138],[-549,-265]],[[33190,43033],[366,76],[104,216],[86,461],[-110,196],[-210,13],[-286,-147],[-143,149],[-19,549],[82,372],[387,300],[48,611],[150,255],[42,557],[226,304],[289,584],[38,200],[-107,837],[-18,473],[106,1123]],[[29488,43729],[299,-266],[181,20],[836,-304],[371,-49],[989,45],[377,52],[470,-101],[179,-93]],[[32836,49466],[-329,-304],[-208,49],[-339,-392],[-45,-192],[-578,-306],[-261,-198],[-352,26],[-283,-296],[-319,103],[-9,-248],[-218,-345],[-406,-406],[116,-242],[-288,-417],[-206,-88],[-113,-279],[-1,-373],[136,-362],[171,-141],[111,-307],[-7,-509],[111,-85],[-31,-425]],[[33190,43033],[37,-378],[-181,-336],[78,-706],[162,-290],[3,-360],[136,-408],[332,-293],[23,-163],[394,-675],[207,-744],[482,-354],[467,-140],[205,-4],[204,-149],[278,-376],[561,44],[514,-34],[504,79],[262,-26],[330,-278],[326,-4],[225,-163],[259,13],[122,-211],[1013,-309],[286,11],[250,-147],[1302,-333],[167,-228],[125,18],[300,-334],[448,-384],[-41,-192],[91,-221],[-40,-201],[433,-699],[386,-345],[360,-680],[175,-56],[-25,-532],[-373,-336],[-173,-329],[-406,-386],[-193,-91],[-170,-357],[-115,-63],[-23,-231],[-191,-19],[-181,-277],[-184,-101],[-188,-245],[-402,-167],[-474,118],[-312,-75],[-342,-219],[-674,-194],[-181,-161],[-127,-290],[-775,-349],[-60,92],[-375,-84],[-444,-239],[-206,-237],[-223,-77],[-174,-179],[-217,-63],[-150,-190],[-291,-64],[-303,-309],[40,-190],[-73,-331],[-131,-160],[-111,-500],[421,-420],[278,-133],[302,24]],[[34339,50398],[-118,-236]],[[43347,46416],[-245,54],[-498,-340],[-139,-38],[-280,-251],[-241,-350],[-574,-291],[-157,305],[165,380],[-158,67],[89,129],[-151,76],[187,252],[-116,317],[399,210],[-85,213],[243,346],[-164,323],[65,217],[-23,478],[-190,154],[130,167],[15,326],[-246,324],[-71,-163],[-273,-42],[-180,77],[-516,-163],[-187,-145],[-395,301],[-137,340],[-483,359],[-242,100],[-262,218],[-1026,377],[-339,-72],[-39,-141],[-678,-14],[-250,-87],[-400,117],[-82,-273],[33,-311],[-104,-162],[-243,250],[-241,-61],[-380,189],[-127,144],[-149,-43],[-263,119]],[[48309,36874],[-792,467],[-138,238],[-165,513],[-698,97],[-210,-31],[-376,87],[-67,266],[-195,310],[-61,381],[-161,237],[23,516],[-84,472],[133,139],[-258,395],[33,186],[-171,287],[138,196],[-7,295],[-218,317],[135,738],[111,5],[14,264],[111,48],[18,378],[162,235],[-17,460],[-272,27],[-214,111],[15,151],[-216,171],[-409,123],[-372,-79],[-373,168],[-343,534],[-157,414],[-164,112],[283,314]],[[37149,25613],[167,140],[310,462],[348,56],[352,180],[131,321],[531,-262],[347,-294],[197,-48],[275,61],[346,-142],[341,-20],[-55,-387],[-271,-963],[33,-566],[179,-690],[544,-416],[216,204],[123,379],[319,608],[320,951],[494,616],[118,453],[265,297],[326,535],[313,287],[102,298],[207,317],[369,393],[124,294],[237,246],[186,-24],[340,134],[278,437],[368,328],[260,91],[387,389],[226,41],[314,208],[352,387],[483,165],[267,411],[401,126],[262,236],[157,378],[-254,476],[-219,299],[-127,-29],[-1094,1255],[-359,565],[50,572],[-158,97],[-56,215],[90,96],[624,227],[-25,202],[322,240],[166,-99],[135,66],[476,462]],[[25802,40008],[187,-574],[301,-522],[315,-407],[341,403],[784,352]],[[26849,40535],[-255,-241],[-171,21],[-245,-161],[-376,-146]],[[27730,39260],[-192,594],[-294,428],[-375,173],[-20,80]],[[26688,27837],[-504,-43],[-447,-145],[-91,-186],[-621,-58],[-384,-126],[-447,72],[-461,-3],[-219,-218],[-177,55],[-79,-393],[198,-75],[-59,-121],[-356,-257],[-161,20],[-538,-537],[-118,4],[-762,-583],[-242,-2],[53,-121],[-227,-379],[-456,-297],[-152,-434],[-338,-433],[-261,-101],[-145,-166],[-349,64],[-152,-267],[62,-423],[-214,-216],[-332,-131],[-104,-270],[-283,-334],[196,-21],[-378,-402],[-287,-33],[-192,398],[-387,-349],[-194,-312],[82,-83],[481,-185],[62,-156],[564,-491],[66,-190],[-92,-309],[151,-312],[261,-255],[157,-527],[-60,-159],[-235,-121],[-344,-341],[-126,-284],[145,-43],[277,234],[267,132],[450,72],[113,-377],[147,-144],[-79,-271],[417,-161],[21,-179],[-179,-117],[9,-457],[119,21],[162,-198],[83,-316],[199,-362],[-74,-247],[27,-647],[437,-375],[-32,-124],[-540,-859],[-94,-253],[-275,-478],[-376,-179],[-177,32],[-285,-455],[-245,-103],[-194,-194],[-294,-799],[-272,-390],[-173,-540],[-363,-720],[-87,-512],[-191,-446],[-72,-594],[431,-242],[317,-70],[262,-398],[18,-230],[-200,-178],[-115,-232],[48,-127],[346,-325],[56,-347],[-450,-276],[-255,-357]],[[33644,26268],[-235,154],[-822,80],[-2,352],[-612,263],[-723,99],[-298,115],[13,-172],[-285,144],[-47,-180],[-539,196],[-26,142],[-454,-13],[-525,582],[-224,73],[-692,-153],[-912,-789],[-531,82],[-173,172],[131,422]],[[34804,23582],[-290,173],[-258,823],[-112,179],[-164,498],[254,369],[-130,269],[-460,375]],[[17376,4770],[155,-392],[297,-360],[3,-211],[-198,-264],[333,-438],[458,-327],[456,-124],[304,-329],[328,-8],[529,-358],[119,-164],[4,-353],[171,-119],[185,-363],[237,-313],[332,-204],[443,-13],[485,-154],[386,-276],[294,89],[367,217],[524,418],[216,44],[122,195],[-1,237],[288,209],[541,141],[594,59],[1030,546],[461,155],[287,264],[153,-26],[532,182],[216,12],[550,177],[740,78],[154,-133],[417,-16],[49,-78],[493,-264],[338,40],[353,-105],[486,-20],[354,220],[596,594],[65,120],[329,211],[108,492],[-48,197],[-210,149],[23,371],[449,381],[25,-85],[318,186],[43,232],[424,37],[93,609],[-10,381],[-330,583],[-463,725],[-122,289],[-462,696],[-93,265],[-274,350],[-204,410],[-157,115],[-545,700],[146,181],[-12,254],[-168,78],[-472,608],[-168,270],[346,948],[150,537],[341,143],[254,36],[277,291],[52,150],[577,388],[-1,181],[144,147],[287,479],[-243,499],[322,517],[381,-136],[97,181],[324,-23],[211,571],[123,148],[-174,414],[-24,471],[260,87],[285,272],[38,188],[-126,284],[360,488],[-202,473],[32,273],[-58,532],[102,-16],[25,263],[-245,90],[-140,508],[-129,228],[-88,389],[271,255],[120,321],[13,965]],[[27730,39260],[293,97],[326,201],[173,-332],[323,-184],[349,-486],[596,-257],[-149,-138],[386,4],[343,-210],[598,-712],[-30,-127],[266,-206],[-105,-171],[312,-95],[-22,-211],[-189,-327],[-187,-122],[7,-395],[-95,-76],[-142,-387],[187,-221],[-23,-416],[-148,-88],[-102,-270],[227,-160],[43,-191],[406,-271],[106,-145],[-124,-353],[-191,-214],[-43,-428],[-247,-301],[10,-341],[248,-434],[240,114],[123,159],[167,-296],[458,-23],[506,143],[258,-91],[-65,-111],[53,-380],[-254,-424],[615,-11],[183,295],[601,468],[-3,-467],[-125,-1033],[134,-204],[-96,-127],[143,-844],[424,-649],[379,-201],[-843,-768],[-187,-77],[-199,-498]],[[29488,43729],[-41,-427],[20,-558],[-166,-157],[0,-207],[-251,-103],[-370,-481],[-337,36],[-37,-173],[-481,-249],[-560,-230],[-315,-377],[-101,-268]],[[34804,23582],[485,274],[718,60],[675,351],[142,223],[100,398],[266,371],[-41,354]],[[18427,38627],[93,-162],[307,-129],[101,138],[146,-135],[-77,-155],[328,-162],[507,-92],[599,-46],[194,27],[285,232],[12,163],[212,-73],[743,228],[321,-24],[299,230],[31,128],[266,28],[592,327],[287,45],[249,-90],[314,81],[159,-117],[281,88],[498,396],[194,332],[434,123]],[[17359,40113],[739,-225],[-129,-166],[325,-349],[199,-382],[-66,-364]],[[16976,45130],[551,-365],[357,-335],[-168,-252],[-161,-25],[-212,-628],[-65,-429],[-172,-53],[-362,-440],[3,-429],[256,-691],[-81,-190],[398,-849],[39,-331]],[[19790,49542],[-526,-146],[-180,-242],[-288,-214],[-283,-445],[-556,-435],[-550,-249],[-352,-261],[-114,-163],[-207,-1071],[124,-518],[32,-568],[86,-100]],[[29243,50840],[-393,-117],[-175,-160],[-392,-197],[-331,-441],[-186,-61],[-320,-606],[-210,-187],[-573,-283],[-155,-16],[-650,253],[-684,11],[-682,115],[-551,-136],[-1118,289],[-647,384],[-664,-93],[-677,-187],[-533,176],[-512,-42]],[[32836,49466],[-287,152],[-245,39],[-145,252],[-250,56],[-76,162],[-331,133],[-562,472],[-316,16],[-202,199],[-266,-163],[-290,4],[-257,-139],[-366,191]],[[18427,38627],[24,-218],[-829,47],[-322,259],[-453,287],[126,-421],[-398,-291],[-27,-228],[321,-257],[98,-315],[299,-32],[417,-433],[585,-36],[182,-59],[295,-259],[425,-272],[-448,-200],[-505,-107],[-247,-189],[85,-356],[-329,221],[-161,-166],[-71,-381],[115,-356],[221,-147],[13,-206],[187,-248],[288,-47],[289,-339],[12,-129],[334,-438],[328,-270],[0,-164],[304,-160],[195,-189],[74,-256],[116,23],[274,-280],[366,4],[153,-80],[141,113],[252,-220],[207,-11],[376,255],[457,60],[119,116],[95,-269],[-77,-150],[160,-437],[330,-58],[250,-250],[248,-571],[128,-451],[-77,-72],[6,-418],[337,11],[-117,-148],[123,-159],[319,-121],[-188,-224],[190,-27],[-90,-202],[303,-212],[-87,-673],[141,-22],[445,412],[-6,101],[330,104],[248,204],[145,-92],[305,337],[46,-49],[345,301],[66,-73],[246,122],[235,-43],[51,-361],[-111,-411],[111,-268],[-77,-246]],[[43347,46416],[102,244],[272,188],[-75,211],[498,187],[112,410],[271,210],[192,525],[182,105],[138,297],[218,234],[38,201],[-76,322],[49,152],[408,242],[31,397],[368,591],[178,587],[112,110],[-1253,254],[-693,346],[-544,166]],[[37093,54392],[-374,77],[-574,-145],[-458,174],[-568,462],[-459,177],[-266,-122],[40,-502],[-161,-383],[-343,-347],[-40,-311],[559,-1472],[-32,-360],[-117,-566],[39,-676]],[[43875,52395],[-651,215],[-302,41],[-506,-35],[-425,35],[-518,224],[-280,418],[-128,329],[-283,299],[-209,-84],[-147,-273],[-260,-6],[-227,350],[-240,247],[-156,590],[-133,103],[-86,-249],[-156,-38],[-295,188],[-182,-75],[-242,-236],[-363,-96],[-640,-2],[-353,52]],[[17359,40113],[-231,-231],[-309,-41],[-272,-161],[-438,-367],[114,-465],[-35,-369],[67,-215],[33,-470],[158,-101],[-111,-196],[-544,-382],[-227,-226],[-181,33],[-397,-102],[-305,-243],[-271,-297],[-99,-202],[148,-402],[6,-227],[-154,-298],[122,-415],[-94,-624],[-376,-455],[-450,27],[-210,-228],[-430,-88],[-127,-266],[132,-283],[-119,-408],[-143,-94],[-77,-243],[-217,-307],[-379,-758],[-403,-304],[-676,-82],[-521,82],[-299,239],[-720,51],[-487,-308],[-92,-116],[-545,-177],[-640,-347],[-551,-197],[-136,-107],[-574,-177],[-280,-189],[-346,-414],[-114,-327],[-199,-323],[-222,-784],[-285,-423],[255,-43],[597,-307],[305,-339],[164,-44],[518,54],[144,-136],[188,-545],[213,-212],[-136,-213],[72,-390],[-414,-427],[-10,-188],[302,-140],[-196,-119],[-255,-18],[-185,-178],[-314,-449],[-283,-540],[-91,-344],[45,-302],[-348,-19],[-193,-352],[-520,-242],[-486,8],[-581,-258],[-291,-353],[-64,-513],[104,-118],[2,-322],[144,-291],[26,-333],[-102,-764],[76,-136],[305,-71],[299,38],[356,-195],[66,-637],[548,-221],[164,-152],[-111,-455],[47,-188],[-174,-139],[-80,-323],[66,-178],[89,-748],[-115,-379],[16,-313],[282,-325],[91,-216],[53,-723],[338,-241],[650,-1076],[2738,-1166],[1306,-662],[2673,-1457],[946,-683],[1151,-990],[775,-645],[748,-533],[614,-1047],[-4,-38]],[[59442,97085],[-1134,86],[-232,203],[-315,7],[-348,-104],[-862,-2863]],[[62716,93488],[-291,180],[-501,-80],[-539,1],[4,289],[-342,228],[-360,-2],[-525,931],[141,108],[-456,1017],[-110,379],[68,29],[-237,580],[-126,-63]],[[56883,92663],[527,-521],[725,-469],[403,285],[44,-73],[404,-23],[164,79],[443,42],[425,193],[345,75],[268,228],[539,145],[261,-70],[581,53],[78,208],[-114,329],[620,11],[120,333]],[[56551,94414],[332,-1751]],[[76733,74085],[-824,-39],[-436,747],[-278,-165],[-523,-224],[-51,448],[-208,-63],[-365,148],[-168,-78],[-252,208],[-693,48],[-231,82],[-357,-277],[-446,242],[-113,335],[-367,-41],[-935,-354],[-569,-185],[-118,85]],[[77311,72692],[-229,1191],[-132,212],[-217,-10]],[[73539,69438],[592,230],[140,-53],[395,294],[686,271],[558,113],[786,309],[171,-144],[310,261],[-68,369],[-166,69],[117,648],[-99,90],[45,229],[198,6],[107,562]],[[70329,72090],[85,190],[426,-65],[31,162],[464,94],[72,-680],[387,-70],[193,213],[410,16],[-213,-252],[388,-219],[-50,-139],[203,-107],[-201,-43],[-68,-413],[118,-82],[-102,-147],[114,-159],[-85,-193],[125,-154],[161,32],[587,-311],[165,-325]],[[69799,75002],[-349,-308],[106,-486],[-10,-604],[783,-1514]],[[66970,57411],[209,168],[128,-129],[375,294],[-39,205],[1019,808],[1352,1161],[460,155],[220,-34],[381,237],[379,391],[627,933],[300,287]],[[57630,60318],[290,-616],[249,-290],[705,-322],[2,-109],[686,-543],[395,237],[412,-292],[143,-162],[-502,-894],[509,-57],[871,-175],[571,534],[571,-194],[129,-435],[174,-277],[1049,1187],[220,194],[461,73],[237,-124],[628,-693],[254,-148],[414,-26],[620,36],[252,189]],[[58571,62085],[-753,-278],[-338,-177],[-230,18],[-154,-136],[222,-396],[265,-172],[47,-626]],[[69900,64930],[-258,-11],[-470,-350],[-86,232],[-158,41],[-332,-233],[-58,-385],[-136,-323],[-124,-57],[-694,22],[-252,74],[-305,-146],[243,-371],[-562,-303],[-332,-4],[-528,-184],[-320,-173],[43,-244],[-315,-187],[-287,72],[-434,-120],[-429,-365],[-303,50],[-1263,-823],[-184,-47],[-56,-214],[-257,-14],[-424,-158],[-148,130],[-292,-190],[-220,32],[-356,171],[-819,540],[-103,-195],[-532,172],[-522,569],[-56,147]],[[73884,65815],[-385,-10],[-184,-168],[-233,15],[-221,-145],[-425,428],[-794,-244],[-299,11],[-387,-140],[-394,-554],[-284,-89],[-378,11]],[[72381,61887],[827,581],[545,596],[-520,178],[426,301],[-242,77],[45,473],[126,172],[210,89],[-347,376],[23,237],[-145,64],[135,249],[412,72],[-63,332],[71,131]],[[56939,85379],[351,-312],[208,-261]],[[56067,89610],[-150,-131],[343,-545],[-211,-304],[122,-634],[-150,-159],[232,-581],[127,-202],[163,-513],[-47,-109],[177,-157],[-94,-153],[244,-418],[116,-325]],[[57498,84806],[752,264],[307,229],[103,-313],[307,52],[-188,294],[130,44],[-6,253],[131,486],[455,70],[112,476],[259,57],[-147,330],[461,233],[113,-107],[369,250],[318,348],[-75,272],[-213,161],[102,144],[733,341],[-280,558],[-238,282],[-166,-59],[-149,119],[-541,-114],[-216,52],[-187,553],[-236,-199],[-126,305],[-93,-27],[-150,459],[-722,-204],[-50,122],[-574,-393],[-365,-182],[-57,140],[-262,-138],[-43,139],[-344,-58],[-147,-131],[55,-399],[-563,95]],[[75504,66307],[-145,127],[146,248],[-413,218],[-933,-82],[-48,565],[-288,114],[-141,-43],[35,288],[-255,171],[-181,-74],[-242,329],[304,88],[778,456],[-247,302],[-407,252],[72,172]],[[73884,65815],[450,33],[93,-79],[254,103],[158,214],[353,-41],[312,262]],[[66386,67793],[-218,-364],[74,-157],[320,-182],[-251,-170],[-308,-50],[-331,-400],[105,-88],[-219,-314],[288,-213],[247,178],[494,-313],[246,149],[401,119],[30,202],[193,72],[357,-39],[74,262],[332,94],[92,-62],[532,71],[176,-81],[263,-379],[479,-130],[-216,-390],[121,-438],[177,-23],[56,-217]],[[66485,71681],[-81,-643],[49,-192],[138,-17],[619,219],[-30,-413],[-232,-160],[-101,-387],[-585,-251],[-144,-245],[-341,-69],[-511,-754],[147,-29],[3,-173],[308,40],[227,-394],[250,-1],[-5,-179],[190,-240]],[[70329,72090],[-813,-394],[13,-229],[-274,33],[-18,146],[-330,10],[-155,129],[-24,385],[-430,-49],[-150,-372],[-569,183],[-365,-43],[-5,-267],[-368,77],[-356,-18]],[[62624,81883],[911,515],[598,265],[316,23],[199,210],[472,82],[270,-93],[442,168],[551,645],[-146,261],[188,38],[-480,635],[239,48],[81,237],[295,208],[218,248],[-348,218],[769,382],[384,53],[179,153],[205,539],[354,-117],[191,89],[515,-134],[235,88],[-41,216],[-349,441],[173,131],[756,-101],[296,192],[335,38],[269,120]],[[57498,84806],[116,-228],[51,-585],[407,90],[-33,151],[366,66],[58,310],[166,109],[94,-359],[-98,-85],[323,-547],[133,-118],[33,-322],[-367,-102],[74,-257],[-172,-151],[69,-227],[-111,-72],[110,-269],[184,-82],[-77,-236],[118,-396],[203,-269],[64,-286],[108,2],[83,-262],[-67,-114],[124,-305],[-112,-231],[207,45],[268,243],[326,116],[68,115],[278,74],[183,263],[343,317],[455,145],[68,-80],[1083,614]],[[56883,92663],[-745,-422],[-3,-275],[-383,-70],[90,-367],[-37,-183],[150,-296],[106,-11],[220,-462],[-241,-104],[185,-477],[-158,-386]],[[67781,93885],[-581,-198],[-333,-418],[56,-103],[-481,-495],[-291,-131],[-201,-178],[-201,-8],[-487,348],[-76,-61],[-353,135],[-188,195],[-267,130],[-145,-44],[-272,92],[-399,-40],[-128,178],[-318,234],[-400,-33]],[[70701,87681],[-74,219],[-142,74],[25,343],[-218,505],[-78,703],[-168,410],[-26,466],[85,136],[8,370],[-127,187],[-323,858],[-208,204],[-324,536],[-491,600],[-231,-150],[-232,175],[-81,-56],[-315,624]],[[65435,71732],[73,-363],[-165,-147],[-44,-471],[180,-187],[179,-51],[276,807],[369,367],[182,-6]],[[63013,81170],[1027,-1894],[186,-162],[181,-411],[299,-392],[559,-472],[297,-1465],[167,-200],[-607,-231],[-174,-155],[-244,-76],[-42,-443],[313,-399],[108,-238],[111,-557],[143,-86],[480,163],[156,-267],[327,-96],[-76,-236],[-419,-809],[87,-65],[0,-460],[-99,-198],[-271,-11],[-87,-278]],[[69799,75002],[-553,420],[-79,464],[-326,643],[-247,411],[-374,-109],[-198,694],[-130,626],[75,311],[-102,404],[-409,490],[-241,-57],[-280,45],[-5,456],[-115,345],[-210,130],[-194,-109],[-188,295],[-336,-118],[-144,65],[-57,763],[-499,-179],[-40,717],[-243,238],[-772,-227],[-1119,-550]],[[76733,74085],[-46,512],[38,136],[-475,389],[-159,341],[-374,479],[-319,245],[-272,73],[218,286],[-238,295],[-150,23],[122,145],[-193,109],[58,196],[-317,301],[-40,288],[-461,140],[46,268],[-258,239],[-134,366],[34,668],[-149,453],[188,45],[43,405],[-217,-12],[8,448],[-271,376],[-381,361],[-446,807],[-152,378],[25,744],[-235,399],[-78,352],[96,373],[-183,63],[-26,452],[-133,47],[-188,714],[-845,167],[-108,277],[201,309],[78,626],[-339,313]],[[62624,81883],[389,-713]],[[75504,66307],[272,167],[289,273],[329,-256],[106,-2]],[[83668,71083],[-163,144],[-884,-48],[-86,-34],[-237,217],[-377,-99],[-509,241],[-94,-85],[-426,108],[-544,17],[-380,-160],[-336,84],[-260,-86],[-25,343],[-170,393],[-949,231],[-138,147],[-162,-49],[-342,204],[-275,41]],[[82832,70240],[272,395],[291,283],[273,165]],[[82297,68435],[132,300],[196,1002],[207,503]],[[76500,66489],[560,537],[606,217],[-37,56],[422,92],[778,6],[702,-81],[23,172],[745,-4],[347,42],[486,164],[288,188],[408,429],[-4,128],[197,-52],[276,52]],[[60928,72069],[-161,-59],[-75,-345],[-180,6],[-122,-266],[57,-206],[255,-78],[-46,-241],[-281,-38],[-118,-317],[-296,-21],[-100,-456],[-276,-10],[-638,-208],[-65,85],[-310,-136],[-431,137]],[[65435,71732],[-182,-60],[-108,238],[-537,-93],[-92,264],[-254,172],[-576,490],[-618,73],[76,348],[-278,-16],[-522,84],[56,-341],[-69,-473],[-210,-256],[-276,-204],[-207,40],[-452,-159],[-258,230]],[[59194,68182],[496,-67],[246,-86],[57,-167],[431,-386],[460,-26],[497,-119],[793,3],[576,168],[161,-155],[391,176],[-28,-390],[626,-106],[343,155],[250,-139],[132,137],[454,-50],[29,186],[312,208],[393,-40],[200,201],[117,-85],[256,193]],[[58141,69916],[-168,-333],[8,-193],[378,-162],[-113,-270],[397,-188],[-72,-250],[195,-35],[428,-303]],[[58532,75340],[707,-68],[-116,-110],[585,-131],[-41,-248],[350,-159],[211,228],[167,-121],[340,-61],[-39,-641],[211,6],[334,-299],[-256,-176],[10,-361],[188,-221],[91,-499],[-236,-446],[-110,36]],[[56939,85379],[-114,21],[-465,-283],[421,-503],[-213,-132],[198,-268],[201,-565],[-30,-694],[83,-458],[-76,-308],[105,-99],[-51,-194],[100,-172],[-11,-266],[196,-127],[-58,-378],[210,-484],[198,137],[104,-180],[347,-224],[-271,-147],[77,-166],[295,-174],[-259,-106],[-237,5],[427,-527],[-147,-571],[288,26],[-108,-333],[26,-653],[124,-85],[-251,-523],[294,-309],[-231,-49],[-10,-330],[84,-334],[120,-172],[284,-11],[59,-140],[-116,-263]],[[59194,68182],[109,-585],[-151,-459],[-281,-290],[-341,-218],[-238,-225],[691,-417],[-97,-185],[-131,-614],[-147,-145],[-128,-325],[-124,-541],[-159,-227],[-77,-272],[-25,-579],[-153,-357],[111,-475],[518,-183]],[[67781,93885],[-278,383],[-174,377],[-120,821],[-127,376],[380,669],[223,106],[236,383],[-804,283],[-424,397],[-341,467],[-405,352],[-227,136],[-860,184],[-132,221],[-709,-290],[-324,41],[-129,491],[-791,-179],[-524,-5],[-340,843],[-113,58],[-510,-185],[-384,47],[-275,-88],[30,-186],[-287,-137],[133,-311],[-131,-73],[-36,-247],[-590,-92],[71,-201],[-251,-26],[-167,-173],[67,-479],[-242,-50],[30,-304],[186,-409]],[[76805,55326],[504,386],[712,382],[482,306],[1235,413],[381,158],[554,366],[65,-94],[544,361],[236,-51]],[[74313,57363],[149,-116],[262,12],[312,203],[371,-487],[-320,-296],[343,-330],[512,54],[316,-255],[-64,-153],[132,-86],[128,-306],[149,88],[202,-365]],[[77965,60651],[-11,-323],[-515,-225],[-26,-110],[-1066,-430],[26,-334],[-252,-183],[-115,-431],[-385,-321],[-517,-69],[-22,-209],[-567,-416],[-202,-237]],[[79700,61073],[-229,46],[-131,-147],[-323,-97],[-251,-152],[-364,37],[-79,109],[-358,-218]],[[81471,58057],[-61,305],[116,516],[480,274],[249,278],[-305,220],[-378,-47],[-105,177],[-163,-34],[20,352],[-195,59],[-241,215],[-438,592],[-65,169],[-239,-330],[-345,35],[-101,235]],[[81518,57553],[-105,322],[58,182]],[[77905,63842],[-252,-8],[-100,271],[-333,71],[-224,139],[-74,512],[511,472],[-147,403],[150,878],[-90,59],[-846,-150]],[[76879,62793],[-28,107],[473,566],[71,-47],[510,423]],[[72381,61887],[1176,-91],[399,-126],[562,198],[301,-202],[300,-293],[497,451],[704,476],[559,493]],[[81246,63227],[-675,396],[-119,116],[-422,160],[-119,110],[-691,132],[-259,-107],[-337,233],[-134,218],[-421,-518],[-164,-125]],[[79700,61073],[178,369],[289,351],[364,122],[-104,132],[117,136],[-38,366],[210,211],[401,205],[190,-98],[116,158],[-177,202]],[[76879,62793],[562,-362],[315,-81],[-100,-437],[246,-215],[-176,-151],[-88,-327],[195,-244],[132,-325]],[[66970,57411],[168,-192],[-6,-183],[144,-233],[10,-318],[275,155],[346,-291],[513,186],[1965,1126],[76,-144],[363,-347],[209,58],[377,307],[228,78],[259,-199],[159,29],[378,-120],[160,-131],[248,168],[645,-78],[162,82],[124,-97],[540,96]],[[82297,68435],[-95,-199],[87,-165],[474,-148],[240,115],[299,-97],[431,-16],[463,-165],[176,78],[593,794],[-368,291],[-385,211],[-560,405],[-363,114],[-457,587]],[[92219,54201],[-1233,954],[-552,313],[-579,268],[-216,190],[220,215],[-685,526],[-297,123],[-436,-62],[-347,89],[-64,172],[-251,126],[-251,-14],[-4363,-1166]],[[84837,54983],[1672,-951],[737,-169],[1025,-176],[2019,-118],[696,222],[366,-110],[265,321],[602,199]],[[83165,55935],[1672,-952]],[[68841,49307],[320,-685],[-73,-513],[-147,-11],[316,-448],[-265,57],[-337,-367],[-169,-495],[-225,-38],[-509,83],[-177,-125],[-198,59],[-239,-211],[-176,-329],[-305,-69],[-481,-6],[-502,-284],[-163,-246],[-68,-576],[-329,-296],[-417,109],[-374,24],[-432,-200],[-1066,-366],[-467,-239],[289,-752]],[[74847,51419],[-1448,-308],[-256,-396],[1,-328],[-162,11],[-124,197],[-386,-88],[-176,-154],[-8,170],[-207,-73],[-23,334],[-159,170],[-413,-225],[-585,80],[-430,316],[-444,-160],[-289,-164],[-158,5],[65,-273],[-344,-1055],[-460,-171]],[[78564,48153],[-2140,394],[-1577,2872]],[[62647,43383],[799,380],[659,-11],[210,-109],[357,-13],[616,111],[293,-330],[560,-231],[755,-83],[305,274],[445,48],[-29,144],[144,234],[320,-64],[238,101],[285,-34],[396,59],[376,-98],[184,60],[683,17],[1058,271],[2324,-2031],[4939,6075]],[[55446,49705],[262,-234],[356,-109],[223,-355],[333,-390],[-208,-1801],[468,-527],[176,-369],[502,-234],[172,-374],[338,-332],[265,-172],[-35,-658],[388,-640],[-14,-312],[297,-12],[185,-438],[214,-260]],[[59522,51650],[-406,-244],[-324,-260],[-577,-299],[-242,-191],[-285,-116],[-838,-7],[-788,-276],[-537,-114],[-184,-211],[105,-227]],[[68841,49307],[-772,1747],[4,147],[235,338],[-124,330],[-691,597],[-827,185],[-972,468],[-438,112],[-467,-123],[-309,91],[-186,-25],[-2,-144],[-259,35],[-477,-39],[16,-157],[-737,-151],[56,-140],[-261,-16],[-434,-150],[41,-73],[-847,-383],[-1239,-324],[-346,68],[-283,-50]],[[59368,42488],[239,-286],[33,-167],[383,-454],[280,-216],[645,282],[-11,152],[299,373],[445,322],[172,207],[94,261],[700,421]],[[57630,60318],[-167,-154],[-881,-528],[-139,-17],[25,-235],[-75,-665],[-172,-129],[-310,94],[-325,-78],[-36,90],[-478,-78],[-266,-341],[-203,-162],[25,-204]],[[74847,51419],[1448,308],[631,266],[-302,596],[-371,19],[-88,232],[-321,219],[-101,665],[225,56],[169,188],[-286,167],[252,233],[-5,110],[272,17],[254,114],[197,-98],[143,186],[-144,353],[-15,276]],[[54628,57911],[179,-487],[264,-178],[638,-39],[418,-335],[770,-316],[425,-54],[254,98],[312,-392],[324,122],[140,-395],[285,-205],[523,-17],[199,-227],[120,97],[503,-355],[165,-437],[282,-211],[389,-70],[-180,-230],[40,-100],[-262,-329],[-399,-76],[91,-258],[-782,-215],[14,-211],[380,-1107],[-198,-334]],[[87327,47715],[-3167,-350],[-3340,377]],[[80820,47742],[171,-2878],[-291,-303],[22,-162],[411,-429],[703,253],[572,103],[304,158],[426,-183],[696,-27],[243,93],[1333,-373],[340,46],[808,-71],[530,33],[208,130],[-105,124],[-3,546],[139,2913]],[[43347,46416],[487,-238],[363,162],[454,132],[570,-25],[369,361],[148,-132],[345,370],[404,251],[219,-3],[702,471],[459,153],[511,96],[269,2],[277,134],[208,285],[164,-139],[994,528],[44,-80],[312,98],[26,-100],[250,79],[38,-146],[517,167],[299,271],[750,229],[198,-153],[477,83],[59,-64],[649,154],[222,-48],[457,25],[200,197],[658,169]],[[53091,57411],[-342,-210],[-93,64],[-308,-546],[-339,-239],[-619,-236],[-802,36],[-8,-195],[-257,-395],[-203,85],[-153,-82],[-15,-316],[234,-229],[-199,-254],[-3,-333],[-77,-456],[-119,-253],[-312,134],[-435,-273],[-454,-109],[-159,-195],[-127,50],[-474,-44],[-722,-266],[-241,-47],[-1068,217],[-314,-6],[-271,-218],[-237,202],[-275,-7],[-40,96],[-268,-27],[-119,229],[-253,-508],[44,-80],[-188,-605]],[[54628,57911],[-146,-218],[-505,-122],[-135,71],[-439,-250],[-312,19]],[[83165,55935],[-182,-47],[-159,100],[-873,154],[-255,98],[32,198],[-101,201],[-109,914]],[[78564,48153],[1363,1987],[4910,4843]],[[85152,65982],[452,-314],[-476,-411],[381,-303],[148,-248],[-48,-292],[114,-236],[286,-14]],[[85915,68218],[-120,-244],[-597,-23],[45,-223],[198,-67],[3,-265],[150,-160],[-24,-605],[-101,-343],[-317,-306]],[[86009,64164],[532,401],[606,183],[90,78],[878,186],[48,92],[301,-43],[-91,262],[165,380],[439,210],[142,161],[441,13],[349,-68],[196,55],[194,598],[453,-84],[565,-204],[55,-90],[289,133],[92,-223],[252,36],[-16,-139],[501,-68],[840,354],[92,-211],[323,117],[288,-172],[15,-658],[135,-359],[2484,-1129],[62,2638],[-2000,2428],[-1928,-1483],[-172,-337],[-742,-201],[-761,-529],[-221,46],[-122,608],[-214,612],[-332,1860],[-65,272],[-283,-326],[-302,-93],[-344,111],[-284,-35],[29,-137],[-391,-306],[-615,-402],[-488,-147],[100,-81],[-200,-104],[-244,167],[-252,-183],[-324,71],[-153,-213],[-53,184],[-196,-13],[-257,-164]],[[85915,68218],[-296,200],[-67,-251],[-365,390],[-159,344],[55,261],[136,118],[152,475],[-185,31],[-51,150],[120,208],[-122,587],[-266,506],[-192,458],[-143,-154],[-462,-298],[-402,-160]],[[81246,63227],[319,102],[258,283],[191,77],[466,-203],[-56,323],[208,236],[-21,264],[312,-12],[242,96],[269,260],[313,-181],[557,627],[406,597],[85,-105],[357,391]],[[48309,36874],[334,233],[585,124],[777,375],[150,8],[268,244],[204,57],[570,-35],[127,153],[665,481],[1133,-584],[712,-227],[477,-106],[873,138],[745,166],[315,132],[601,77],[843,-69],[429,189],[116,417],[-126,193],[-447,327],[-416,168],[-170,288],[-419,379],[-153,371],[422,403],[41,197],[314,411],[187,417],[262,266],[218,561],[442,-7],[387,-102],[265,-178],[328,147]],[[81471,58057],[526,319],[302,85],[131,232],[363,276],[206,3],[1086,840],[-3,229],[286,324],[25,478],[204,219],[-95,120],[-58,380],[-83,75],[143,367],[-135,208],[110,320],[678,553],[578,802],[274,277]],[[94201,52842],[-50,-99],[457,-648],[52,-679],[178,-380],[178,-199],[-138,-21],[-252,-549],[19,-472],[-313,345],[-509,335],[-101,-537],[-127,-88],[10,-388],[-251,-382],[-100,-392],[-1422,-2064]],[[91832,46624],[1566,-379],[-97,-2486],[804,-180],[787,141],[356,106],[256,3],[1112,492],[240,18],[368,247],[867,84],[397,442],[238,130],[573,141],[37,182],[232,137],[-58,127],[109,441],[146,180],[154,435],[-5,770],[85,274],[-22,491],[-73,317],[-494,356],[-309,109],[-453,57],[-285,-69],[-365,107],[-286,458],[-193,126],[-62,179],[-382,90],[-404,400],[-190,120],[-108,310],[-225,200],[-286,116],[-380,556],[-323,137],[-407,259],[-551,594]],[[87327,47715],[4505,-1091]],[[78564,48153],[2256,-411]],[[94201,52842],[-784,837],[-234,141],[-514,33],[-450,348]],[[47470,77148],[628,-492],[374,-155],[799,-74],[758,208],[313,-12],[505,-138],[496,75],[109,147],[183,-59],[32,251],[161,16],[64,-291],[241,-281],[258,-110],[10,-466],[657,-271],[205,-20]],[[43572,82050],[204,-154],[-83,-62],[328,-394],[20,-199],[174,-115],[-69,-94],[400,-240],[456,-122],[-150,-229],[251,-140],[98,147],[73,-291],[207,20],[216,-323],[266,-122],[-274,-206],[128,-208],[290,-178],[-56,-191],[143,-223],[22,-220],[306,-67],[189,-140],[34,-153],[245,-205],[383,-131],[212,-325],[-205,-135],[90,-202]],[[44935,83590],[-455,-190],[251,-280],[-400,-229],[40,-52],[-507,-209],[-292,-580]],[[49811,87183],[-484,-438],[-144,-200],[-218,34],[-81,-160],[-254,-52],[-453,43],[-68,-111],[-521,-211],[-488,-523],[-228,61],[-7,-298],[-168,2],[-16,-170],[-282,-15],[130,-373],[-134,-22],[-36,-282],[-482,125],[3,-300],[-124,-61],[60,-287],[-71,-82],[-348,-60],[-1,-187],[-323,-168],[-138,142]],[[56551,94414],[-387,-1286],[-280,-72],[-773,-396],[-697,-486],[22,-213],[-304,-354],[-185,-353],[183,-238],[-60,-326],[74,-285],[-141,-47],[52,-323],[-226,-35],[-30,-926],[-80,-277],[214,-21],[-9,-517],[142,-244],[-534,-26],[-554,73],[-532,1],[-139,-54],[26,-215],[-524,-106],[-506,-346],[-214,-56],[-621,69],[-129,-108],[-528,-64]],[[54805,74620],[335,-39],[870,46],[274,-89],[1148,35],[241,93],[409,-3],[257,-70],[122,68],[71,679]],[[53263,75476],[371,-141],[436,-66],[66,-109],[451,-127],[218,-413]],[[35353,86199],[279,-915],[627,-1230],[340,-353],[252,-405],[133,-999]],[[38060,88491],[-74,-51],[144,-546],[-246,101],[-420,-174],[-165,-156],[-362,22],[-212,-241],[175,-304],[-774,-239],[134,-273],[-396,56],[68,-157],[-384,57],[-39,125],[-397,-25],[241,-487]],[[40843,85569],[-612,741],[83,131],[-337,198],[-262,0],[64,184],[-247,283],[-145,-56],[-333,362],[53,71],[-559,170],[336,224],[-378,149],[-446,465]],[[36984,82297],[72,0],[861,715],[270,339],[545,76],[259,297],[751,232],[299,298],[466,642],[134,111],[202,562]],[[36329,60684],[155,96],[70,338],[545,-71],[87,254],[189,-15],[46,350],[-275,1],[63,223],[315,4],[11,253],[-195,288],[187,444],[147,-44],[760,340],[296,317],[258,-156],[417,-136],[215,232],[428,261],[261,61],[355,268],[342,153],[-129,176],[472,181],[15,317],[-74,365],[618,24],[112,53],[308,-97],[40,149],[551,-97],[307,144],[-80,285],[45,346],[-123,88],[92,268]],[[32185,64317],[268,-132],[110,108],[340,-248],[1039,-244],[477,-454],[-77,-63],[397,-367],[634,-268],[235,64],[277,-363],[41,-156],[-107,-276],[-264,-2],[-214,-224],[268,-234],[268,-376],[452,-398]],[[37959,71239],[-88,-204],[-190,-46],[-434,-285],[199,-216],[-281,-131],[-190,-226],[-167,355],[-307,-74],[63,-314],[-427,-620],[12,-164],[-243,-194],[110,-76],[-561,-338],[131,-188],[-230,-11],[-136,-123],[-161,158],[-26,-189],[-206,-188],[310,-311],[-417,-235],[128,-166],[-707,-390],[31,-149],[-505,-238],[121,-428],[-451,-109],[-445,-321],[-43,-305],[-211,-199],[128,-51],[-575,-357],[-6,-589]],[[39064,70779],[-249,408],[-500,-140],[-163,212],[-193,-20]],[[43160,66347],[40,304],[-237,81],[-1068,908],[-19,266],[-328,429],[-624,503],[-445,217],[-663,530],[-292,174],[-54,328],[-330,252],[-76,440]],[[48332,70646],[1454,1940],[401,492],[230,197],[319,-159],[202,288],[135,315],[366,286],[135,-35],[210,218],[227,-151],[173,263],[12,381],[582,171],[223,371],[123,-7],[139,260]],[[44991,73762],[3341,-3116]],[[43816,74858],[1175,-1096]],[[47470,77148],[-485,86],[15,-185],[-146,-60],[-161,112],[-282,-437],[-48,-297],[-290,198],[-229,-38],[-446,-192],[174,-236],[-1756,-1241]],[[44715,84484],[-326,-527],[22,334],[-771,96],[-70,120],[-123,1006],[-299,288],[-456,-35],[-160,-93],[-512,361],[-78,-260],[-1002,-147],[-97,-58]],[[44935,83590],[-205,291],[37,600],[-52,3]],[[40161,80826],[730,168],[611,303],[340,224],[464,179],[12,149],[288,260],[459,255],[507,-314]],[[37329,81513],[935,-168],[445,-177],[1405,2],[47,-344]],[[36984,82297],[84,-530],[261,-254]],[[29819,64648],[134,-25],[215,145],[324,-368],[1173,-470],[261,10],[243,140],[-110,152],[126,85]],[[26565,68945],[-163,-179],[548,-492],[44,-146],[415,-315],[431,-577],[153,187],[532,-142],[-93,-219],[-188,-104],[475,-230],[686,-33],[86,-175],[-250,-358],[181,-75],[-236,-277],[-71,-348],[95,-59],[250,-461],[162,22],[197,-316]],[[32915,74649],[-517,-2],[-500,-154],[-547,-273],[-436,-480],[-146,-629],[-502,-455],[-232,10],[-484,-289],[-357,-122],[-156,-179],[-264,-127],[100,-311],[-159,-76],[-200,65],[-129,-560],[-101,-53],[117,-244],[-113,-125],[-231,59],[-163,-137],[222,-141],[-74,-181],[49,-304],[-290,-56],[-171,-325],[-671,-497],[-395,-118]],[[35225,74405],[-680,87],[-128,226],[-222,4],[-387,196],[-264,5],[-485,-318],[-144,44]],[[37959,71239],[-305,28],[-132,107],[-182,-118],[47,255],[-263,218],[190,83],[-182,154],[92,180],[-275,321],[143,198],[-266,85],[-329,226],[-313,298],[-25,159],[-590,651],[-344,321]],[[55790,72195],[308,-249],[100,-518],[350,-315],[329,-175],[375,-89],[461,-636],[428,-297]],[[54805,74620],[-200,-75],[-484,138],[-332,-280],[263,-205],[-104,-351],[391,-149],[157,21],[411,-104],[-52,-324],[95,-20],[-49,-337],[441,-6],[501,-147],[210,-344],[-263,-242]],[[36161,78959],[261,297],[537,442],[589,236],[352,-85],[-451,767],[50,690],[-170,207]],[[31065,81014],[186,-39],[-19,-244],[256,-237],[320,-102],[179,37],[425,-156],[822,108],[259,88],[93,-123],[-84,-273],[218,-364],[136,-37],[-98,-169],[66,-256],[239,48],[-138,-192],[-16,-391],[-610,-531],[546,-494],[276,8],[200,-262],[386,177],[223,253],[11,140],[303,186],[282,-202],[275,-36],[110,147],[121,637],[129,224]],[[32047,85241],[-103,-404],[0,-270],[-90,-187],[-259,-222],[-237,-471],[370,-47],[433,-222],[-218,-182],[-196,-334],[-357,-149],[0,-293],[-341,-1281],[16,-165]],[[35353,86199],[-802,-172],[50,-692],[-135,-20],[-334,-355],[-803,-176],[-402,135],[-470,-22],[-196,316],[-214,28]],[[37848,77199],[52,80],[-826,427],[-161,206],[-1,366],[-142,255],[-422,383],[-187,43]],[[35225,74405],[203,366],[193,201],[305,475],[-21,351],[134,392],[165,24],[1098,714],[546,271]],[[29265,78078],[909,333],[1380,-245],[328,-373],[191,92],[51,-227],[-362,-574],[539,-87],[44,-492],[-367,-79],[35,-126],[270,50],[66,-254],[249,49],[449,-139],[39,-227],[-158,-424],[50,-447],[-63,-259]],[[29429,80848],[-105,-556],[60,-5],[-50,-499],[-69,-1710]],[[31065,81014],[-155,-167],[-964,-20],[-517,21]],[[50224,68882],[-1389,-1263],[-2,-220],[-607,-574],[23,-87],[-273,-347],[-157,116],[-267,-342],[65,-130],[-313,-151],[-141,-302],[141,-80]],[[55790,72195],[-311,-591],[101,-271],[221,-347],[-112,-128],[-1,-270],[219,-225],[-229,-374],[300,-181],[-204,-245],[210,-129],[14,-223],[-187,-136],[149,-247],[-88,-271],[-244,-367],[-257,-162],[-212,-488],[-310,-78],[-271,-146],[-292,56],[-375,232],[-264,268],[-92,-303],[49,-235],[-457,154],[-229,-308],[-778,266],[-30,-51],[-560,250],[-1326,1237]],[[47304,65502],[171,-150],[23,-382],[631,-755],[261,-189],[227,40],[178,-133],[540,-699],[114,-326],[561,-211],[77,-283],[-120,-778],[90,-722],[217,-404],[334,-123],[101,-326],[422,171],[663,-242],[360,-239],[100,57],[61,-237],[-42,-254],[281,-83],[217,-336],[-57,-229],[-165,-55],[-90,-559],[188,-158],[255,-493],[189,7]],[[43160,66347],[350,-81],[233,-181],[303,-108],[276,200],[259,66],[468,-81],[719,-259],[740,-586],[437,-258],[286,138],[73,305]],[[44991,73762],[-2002,-1415],[-573,-265],[105,-102],[-107,-129],[-389,443],[-414,-381],[-270,-10],[-98,144],[-267,-281],[-59,-345],[-640,-152],[-276,-186],[-183,169],[-754,-473]],[[50224,68882],[-1892,1764]],[[43127,76373],[-1087,-63],[-473,4],[-526,-211],[-37,122],[-421,107],[-669,-335],[-293,-361],[-575,637],[-394,512],[-167,-88],[-356,388],[-82,-76],[-199,190]],[[43816,74858],[-689,1515]],[[42211,90910],[18,-257],[132,13],[430,-381],[-115,-401],[267,-215],[356,-565],[-261,-581],[20,-340],[226,-236],[38,-446],[212,-11],[-8,-343],[246,-259],[-57,-117],[298,-88],[81,120],[202,-29],[97,-164],[148,1],[108,-292],[-129,-756],[143,-824],[-58,-245],[110,-10]],[[49811,87183],[-268,551],[-209,56],[11,175],[179,304],[-256,-4],[-46,130],[-289,-96],[-305,110],[-80,163],[-278,-129],[-149,255],[-136,4],[-253,304],[-173,75],[-159,269],[43,253],[303,187],[-35,149],[-379,317],[-494,-1],[-1,313],[343,131],[491,110],[940,68],[249,200],[199,-343],[581,-10],[174,132],[-38,272],[127,124],[92,311],[372,222],[90,366],[-158,591],[-298,341],[-163,-84],[-152,94],[-87,242],[-296,-169],[-155,22],[-362,-283],[-496,-97],[-228,-156],[-511,-33],[-100,-214],[-125,190],[-160,-16],[-47,-187],[-242,112],[-817,-193],[-597,-182],[-1504,-103],[-359,-111],[-370,-212],[-36,-288],[-592,-340],[-391,-165]],[[36054,59010],[469,-170],[426,-238],[349,-1112],[-40,-440],[-92,-381],[-73,28],[3,-464],[324,-653],[66,-280],[-77,-333],[-297,-284],[-19,-291]],[[36329,60684],[212,-207],[-55,-323],[-277,-602],[-155,-542]],[[40161,80826],[-251,-59],[303,-769],[52,-353],[178,-21],[-65,-224],[95,-234],[215,-85],[140,360],[393,-157],[-263,-323],[304,-137],[656,-375],[250,-236],[-113,-77],[58,-286],[401,149],[101,-287],[-217,-281],[446,-436],[283,-622]],[[39957,91511],[-432,-41],[-528,-422],[189,-916],[49,-558],[-388,-34],[206,-827],[270,113],[36,-155],[-432,-87],[-173,-222],[-359,139],[-335,-10]],[[42211,90910],[-715,479],[-518,60],[-1021,62]],[[26288,91329],[-219,-401],[80,-480],[299,-460],[-166,-304],[-229,-216]],[[39957,91511],[-181,237],[-314,707],[19,523],[-531,766],[-220,262],[-113,297],[-200,241],[-610,171],[-886,331],[-755,-342],[-483,-178],[-263,-45],[36,-258],[-288,-68],[99,-143],[-456,-159],[-213,-337],[-321,-86],[-177,108],[-416,-118],[-550,398],[-600,5],[19,-187],[-314,-62],[73,-483],[197,-370],[683,-847],[-1697,-496],[-45,106],[-3071,-510],[-135,-324],[-456,254],[-475,36],[-381,255],[-644,134]],[[26053,89468],[249,-269],[448,-73],[861,-199],[311,-13],[439,75],[259,-463],[-6,-415],[905,-395],[135,-543],[98,-147],[200,-4],[-34,-445],[-78,-178],[418,-157],[608,-41],[99,-233],[237,-205],[509,-276],[183,-233],[153,-13]],[[36054,59010],[-448,194],[-455,613],[-170,67],[-605,-4],[-424,-47],[-172,-360],[-430,-256],[-9,-198],[183,-192],[247,-90],[-54,-103],[490,-680],[-127,-292],[-258,-75],[-114,-423],[-290,-193],[-43,-347],[156,-135],[18,-251],[-205,-297],[34,-125],[-394,-226],[-902,-15],[-388,-84],[-620,-230],[-1189,-356],[-564,55],[-366,246],[-193,19],[-228,-227],[-177,-314],[-177,-455],[-326,-627],[87,-357],[-210,-2],[-548,404],[-464,-67],[-134,-96],[407,45],[-163,-199],[99,-271],[-245,-334],[-25,-184],[148,-560],[469,-137],[70,-85],[592,-199],[91,-137],[528,-260],[458,-124],[229,-199]],[[21123,72665],[139,-474],[221,59],[283,-130],[219,-555],[294,48],[195,-65],[-5,-426],[121,-197],[196,-100],[-367,-874],[-454,-325],[101,-276],[370,-23],[450,366],[-54,318],[214,95],[-62,192],[226,80],[-270,303],[196,29],[-41,137],[608,26],[-1,-291],[168,-27],[-36,-164],[323,-28],[416,288]],[[24317,74908],[-672,25],[-261,-568],[-357,-110],[-186,58],[-427,-136],[77,-229],[-161,-314],[-622,-398],[-293,-75],[-292,-496]],[[24573,70651],[202,189],[27,610],[-87,813],[427,-15],[-29,706],[68,22],[-8,461],[-210,9],[-112,735],[-222,-1],[-111,123],[32,276],[-233,329]],[[11339,79260],[256,560],[387,-106]],[[6606,77987],[-25,190],[394,289],[141,-94],[284,97],[1024,-193],[435,120],[35,84],[607,-85],[286,182],[47,229],[498,341],[415,111],[592,2]],[[3482,82343],[-81,-145],[172,-343],[-68,-247],[109,-176],[-193,-119],[70,-185],[198,-172],[268,60],[57,-315],[265,-129],[-55,-216],[264,-96],[344,-303],[43,-144],[272,-32],[366,-184],[366,-296],[104,-397],[524,-588],[-143,-64],[242,-265]],[[4744,83619],[-147,83],[-238,-180],[28,-206],[206,-217],[-308,-208],[-226,-67],[-47,-201],[-312,43],[-218,-323]],[[7040,82711],[-290,-152],[-298,50],[6,211],[-174,87],[-68,-141],[-271,54],[-130,146],[-92,435],[-426,132],[-553,86]],[[11982,79714],[-4,186],[-155,334],[-443,227],[-1384,36],[-312,-117],[-343,-37],[134,548],[-294,36],[-572,292],[-36,118],[-423,-4],[10,208],[-281,49],[-334,169],[47,222],[-115,289],[130,218],[-84,191],[-407,-84],[-76,116]],[[12062,82231],[-224,-85],[-4,-256],[222,56],[83,-237],[321,-549],[201,127],[125,-306],[230,-207],[305,-133],[-39,276],[429,258],[588,-340],[-230,-375],[-61,-663],[-541,162],[16,-582],[-304,21],[-430,150],[-767,166]],[[17095,85262],[-105,-85],[-477,-131],[-141,-94],[-161,-372],[31,-766],[-19,-454],[-80,-437],[-268,62],[-7,-259],[-187,-270],[-535,-266],[-423,-83],[-490,162],[-480,91],[-165,-398],[-491,57],[-897,262],[-138,-50]],[[20379,83190],[-233,150],[96,214],[474,393],[-82,184],[-438,621],[97,608],[-462,5],[-704,-126],[-151,-486],[-375,95],[17,141],[-187,149],[-110,-92],[-160,104],[-336,9],[-604,204],[-126,-101]],[[19309,79230],[137,-3],[55,444],[-251,-48],[-441,167],[-395,40],[-183,-92],[-420,172],[-477,411],[256,160],[359,457],[130,57],[138,-156],[271,-40],[354,-176],[494,115],[-36,129],[569,98],[108,88],[41,665],[176,15],[-30,754],[340,554],[-125,149]],[[14064,77006],[1068,-298],[242,-229],[906,-170],[363,169],[197,179],[666,-18],[374,-87],[688,-20],[200,245],[-43,259],[-216,85],[-219,433],[-151,162],[60,610],[144,411],[309,405],[192,90],[465,-2]],[[13144,76730],[496,70],[226,200],[198,6]],[[11902,76984],[168,-5],[346,-297],[346,102],[382,-54]],[[11339,79260],[267,-4],[1,-270],[289,-102],[-57,-533],[-398,-120],[310,-101],[263,-227],[-9,-387],[-220,-393],[117,-139]],[[13497,74746],[501,5],[249,112],[-81,104],[196,168]],[[13132,75450],[233,8],[-44,-385],[176,-327]],[[14086,76065],[-246,-123],[-420,-368],[-288,-124]],[[14362,75135],[-94,571],[-182,359]],[[24508,81631],[542,167],[303,1],[417,87],[33,-250],[710,-203],[321,-166]],[[20379,83190],[744,-191],[380,-267],[243,-288],[411,-40],[241,-89],[730,-50],[188,-109],[648,-177],[544,-348]],[[26053,89468],[-550,241],[-564,-111],[-142,-156],[-841,-345],[-468,-27],[-850,-131],[-282,-89],[-285,87],[-320,316],[-360,144],[-173,149],[-360,63],[-392,-86],[-101,-185],[75,-154],[-255,-116],[-15,-165],[124,-299],[-185,-149],[280,-494],[-377,-55],[60,-265],[-496,-280],[62,-85],[-275,-167],[-335,-505],[-274,-607],[-724,-236],[-165,47],[-161,-160],[-289,-28],[-282,-172],[-38,-186]],[[26834,81267],[8,93],[326,17],[-52,199],[271,334],[63,-100],[263,52],[201,-116],[281,-463],[478,108],[186,-270],[575,-165],[-5,-108]],[[26312,78376],[472,1128],[-160,99],[-617,-22],[86,397],[304,374],[248,-63],[252,68],[-196,238],[-86,394],[209,69],[10,209]],[[20670,79614],[633,-138],[330,-247],[120,128],[217,-486],[481,215],[172,-419],[264,120],[116,-304],[315,416],[387,-453],[224,-157],[-272,-303],[540,-203],[414,-299],[1332,4],[369,888]],[[24508,81631],[-119,-501],[-357,-466],[-197,-48],[-410,100],[-324,-51],[-389,-244],[-406,-75],[-57,-81],[-308,-5],[-238,-244],[-175,-342],[-171,-97],[-354,494],[-443,-345],[110,-112]],[[27362,77489],[253,-594],[-736,-9],[-308,-1511],[-276,-630],[-510,169],[-104,-233],[-483,167],[-301,46],[-213,-127],[-367,141]],[[29265,78078],[-781,-379],[-249,-23],[2,-186],[-875,-1]],[[24573,70651],[254,-277],[340,-15],[207,-106],[233,-239],[256,-387],[325,-351],[377,-331]],[[11902,76984],[-329,-332],[-276,-39],[-104,-124],[-745,-123],[-493,-117],[-195,-140],[-493,-725],[-249,-153],[107,-267],[-262,-203],[-227,-630],[-238,-215],[-21,-252],[106,-134],[44,-329],[-884,-326],[-819,-476]],[[13132,75450],[68,130],[440,431],[-166,128],[-27,-154],[-360,7],[275,608],[-218,130]],[[8058,68572],[131,127],[93,304],[306,501],[223,184],[553,101],[279,158],[69,142],[-45,367],[749,499],[440,161],[470,417],[358,216],[534,69],[158,541],[390,187],[130,308],[-204,272],[100,131],[-158,212],[244,82],[-199,214],[34,189],[424,511],[360,281]],[[7416,68731],[642,-159]],[[6824,72399],[156,-237],[600,-500],[398,-565],[-96,-332],[170,-270],[-185,-348],[104,-245],[-224,-29],[197,-467],[-485,-70],[-43,-605]],[[6606,77987],[-56,-264],[203,-69],[184,-243],[-54,-202],[-295,-361],[-260,-218],[-111,-263],[-223,-158],[55,-159],[-196,-531],[-63,-378],[102,-163],[-57,-306],[269,-1086],[190,-243],[216,-615],[314,-329]],[[7847,82955],[-301,4],[-506,-248]],[[10835,83206],[-177,-317],[-274,-189],[-570,-304],[-264,-90],[-12,96],[-572,-44],[-135,273],[-540,35],[-265,236],[-179,53]],[[12062,82231],[-250,370],[-243,-87],[-390,132],[-344,560]],[[14086,76065],[-83,311],[61,630]],[[15662,44848],[195,-58],[1026,103],[93,237]],[[13027,59258],[155,-163],[55,-329],[179,-153],[264,-373],[-388,-421],[105,-687],[173,-362],[192,-188],[-32,-359],[-174,-110],[-141,-477],[10,-208],[161,-260],[-46,-386],[181,-309],[158,-91],[162,-397],[159,-84],[23,-479],[292,-486],[83,-416],[241,-351],[124,-287],[-204,-137],[-83,-455],[147,-161],[279,-138],[66,-153],[288,-217],[249,18],[263,-314],[49,-359],[-170,-522],[-7,-353],[153,-124],[-230,-244],[-248,-85],[-204,-648],[75,-416],[92,-77],[38,-449],[-29,-412],[72,-556],[99,-250],[110,-681],[-106,-301]],[[22660,52314],[-114,19],[-183,336],[-322,332],[-325,668],[52,161],[474,554],[-95,568],[-180,466],[-19,200],[-244,417],[-111,546],[123,640],[-287,258],[-145,259],[119,154],[-39,215],[105,103],[-65,183],[116,535],[332,284],[141,417],[-157,309],[-339,-88],[-501,0],[-275,80],[109,211],[-40,145],[631,109],[282,133],[42,264],[-256,-24],[-75,379],[-129,-54],[-473,131],[182,462],[-244,573],[123,296],[-280,139],[-469,373],[-548,28],[-488,224],[-355,-75],[-37,-157],[-514,-55],[-46,-69],[-567,-317],[-443,-79],[-762,-313],[-214,170],[-509,97],[-3,582],[-348,-69],[-256,66],[-427,-106],[-626,-241],[-192,-312],[239,-285],[272,-62],[-558,-241],[26,-123],[272,-182],[90,-355],[-150,-224],[311,-167],[-252,-116],[-236,-207],[-191,-278],[67,-178],[-96,-149],[357,-59],[-187,-126],[-139,-265],[-217,-1],[-370,-165]],[[19790,49542],[-191,282],[-10,296],[-297,20],[164,201],[167,40],[97,274],[123,-18],[476,217],[400,295],[34,158],[396,155],[211,217],[358,-88],[314,294],[628,429]],[[13228,63056],[-242,-61],[-186,112],[-86,-93],[-356,122],[-9,492],[-96,166],[-245,-161],[-138,56],[76,343],[-101,177],[-560,-80],[-37,-82],[-377,155],[-57,-384],[-209,-325],[-7,-141],[-229,-401],[-422,-335],[-180,-286],[-358,-732],[-496,-267],[-300,-315],[-492,-634],[-775,-650],[-235,-115],[-303,-303],[-392,-277]],[[13027,59258],[-54,195],[95,199],[-25,289],[135,62],[103,275],[-325,309],[62,306],[192,319],[413,438],[182,576],[-97,231],[-213,59],[-349,326],[82,214]],[[6416,59037],[-89,-64],[-120,-607],[102,-185],[-305,-187],[173,-362],[-74,-192],[-437,-755],[-69,-224],[-185,-47],[-124,-550],[292,-14],[113,-144],[-287,-193],[-96,-219],[-228,-158],[-339,-546],[-201,-502],[220,-56],[91,-249],[-244,-401],[185,-77],[120,-308],[191,-80],[-38,-144],[205,-288],[228,-78],[343,-737],[315,46],[394,-145],[274,52],[374,-684],[-128,-378],[111,-322],[161,-161],[381,-150],[244,-221],[393,-61],[309,-500],[-81,-594],[219,-525],[306,-143],[197,-188],[354,-480],[-61,-293],[-159,-285],[-267,-249],[-38,-137],[191,-526],[252,-520],[287,-270],[412,112],[400,9],[633,216],[221,125],[453,-10],[555,308],[293,93],[450,-33],[119,-136],[-23,-188],[170,-318],[367,-323],[97,48],[397,-268],[548,89],[461,-3],[238,191]],[[29819,64648],[-269,-169],[49,-85],[-402,-268],[-396,57],[-156,-64],[-253,-385],[-99,-270],[-238,-406],[-298,-299],[80,-149],[-210,-247],[143,-233],[197,-78],[13,-299],[-649,-360],[-242,-274],[-243,-47],[-339,119],[-174,-206],[140,-378],[-22,-170],[257,-489],[323,-203],[-39,-314],[231,73],[245,-51],[172,-205],[-85,-196],[207,-321],[-278,-588],[-274,141],[-165,-260],[-14,-252],[-177,-124],[-69,-319],[173,-214],[-196,-145],[-405,-35],[-881,-356],[-485,-418],[-631,0],[-243,-573],[-306,-308],[203,-188],[-81,-728],[248,-342],[-77,-181],[-326,-352],[-174,-56],[-335,-248],[-325,-546],[-284,-325]],[[19309,79230],[286,-98],[138,119],[562,-216],[149,337],[-177,30],[40,193],[363,19]],[[10835,83206],[-16,143],[177,72],[43,476],[215,129],[777,713],[-568,276],[51,564],[202,1],[387,703],[282,153],[107,198],[198,85],[98,188],[-193,346],[81,479],[220,196],[-88,199],[273,133],[-110,267],[76,284],[-343,233],[63,132],[-88,346],[10,250],[-165,245]],[[4744,83619],[-195,208],[-593,395],[-338,694],[181,68],[-209,421],[290,128],[-200,312],[-411,-249],[-193,504],[153,294],[271,51],[-70,182],[169,284],[165,35],[66,349],[137,34],[257,-148],[551,240],[24,321],[-194,360],[286,127],[305,-480],[509,-136],[103,-254],[-241,-152],[544,-348],[205,11],[929,-484],[806,69],[24,71],[336,-144],[58,-306],[325,63],[349,-278],[285,-145],[266,-9],[349,-300],[208,-25],[-1,-281],[-224,-84],[4,-238],[149,-173],[201,-32],[-491,-225],[-14,-205],[-382,78],[-80,-218],[-258,-211],[-317,-118],[-275,30],[-120,226],[-111,-16],[50,-319],[-332,-114],[-203,-527]],[[12524,90017],[-111,20],[-1031,804],[-599,361],[-1880,-175],[-4374,-1151],[-1819,-818],[-255,-141],[-1497,369],[-151,265],[-414,-20],[-35,-223],[-162,-170],[-57,-251],[134,-102],[-166,-163],[74,-152],[-148,-196],[93,-326],[14,-523],[-140,-69],[194,-313],[160,53],[96,-127],[325,-157],[232,-442],[70,-250],[459,-148],[68,-181],[-88,-262],[178,-225],[71,-358],[367,-687],[182,-56],[-1,-312],[177,-126],[178,-294],[-119,-189],[240,-141],[94,-290],[274,-249],[-11,-87],[336,-172]],[[25952,94815],[-132,-83],[-407,-45],[-400,-212],[-272,-38],[-339,56],[-147,177],[-364,159],[-1034,-524],[-237,-34],[-2,389],[-181,-49],[-6,134],[-314,-3],[-461,-188],[-319,-185],[-643,-478],[-575,-75],[-618,-187],[32,128],[-572,-171],[-588,-340],[-55,67]],[[26288,91329],[-30,705],[173,435],[-69,387],[2,624],[150,142],[-168,253],[58,415],[-249,218],[-203,307]],[[18318,93313],[42,-99],[-1129,-839],[-1185,-1275],[-902,-555],[-539,-486],[-383,-404],[-617,109],[-592,161],[-489,92]],[[27362,77489],[-248,0],[368,888],[-1170,-1]],[[17946,72726],[475,-31],[881,50],[451,149],[52,-201],[90,182],[357,141],[317,-362],[285,-53],[269,64]],[[14362,75135],[464,-386],[332,77],[236,-357],[446,323],[547,-232],[-450,-264],[-65,-107],[317,31],[318,-64],[266,-171],[-349,-378],[197,-214],[330,-151],[26,-257],[554,225],[103,140],[30,-304],[359,-194],[-77,-126]],[[13161,66338],[-68,57],[-296,-277],[-89,-166],[-150,133],[-343,-83],[139,-575],[-23,-192],[-611,-115],[128,248],[-481,133],[-470,232],[-171,10],[-31,322],[116,486],[-199,59],[42,539],[-497,-41],[-45,559],[-361,29],[-169,145],[3,192],[-259,-48],[-219,56],[-161,152],[-412,58],[27,105],[-503,216]],[[13228,63056],[-64,173],[162,257],[-435,468],[-344,144],[135,83],[299,-4],[90,436],[238,-91],[263,124],[126,167],[-294,18],[-28,231],[-149,230],[208,178],[162,582],[-436,286]],[[7416,68731],[-270,-93],[84,-94],[-1667,-703],[-584,-313],[-257,-312],[-115,-433],[-6,-398],[246,75],[181,-275],[-56,-395],[-185,-304],[750,-275],[253,-214],[-96,-452],[-189,-341],[63,-418],[194,54],[219,-356],[-108,-274],[-119,-78],[28,-193],[-178,-200],[347,-127],[526,-320],[37,-194],[-271,-308],[283,-203],[137,-641],[136,31],[-211,-612],[43,-218],[-321,-492],[276,-137],[-116,-191],[-387,-126],[333,-164]],[[25952,94815],[-340,342],[-165,70],[-234,396],[-523,597],[2,176],[-135,460],[62,351],[-1403,1389],[-1223,-1084],[-1966,-312],[-265,315],[-2293,132],[-786,-409],[43,-286],[-256,-152],[86,-479],[183,-341],[166,-131],[-61,-379],[188,-117],[243,-351],[128,-528],[377,-153],[200,-413],[-51,-274],[389,-321]],[[13161,66338],[105,520],[510,202],[376,-22],[306,105],[-27,96],[316,105],[565,-29],[209,126],[147,-112],[261,149],[18,137],[231,208],[38,176],[-466,98],[-18,123],[509,307],[-346,267],[384,427],[-134,200],[559,159],[166,119],[-77,126],[1,1172],[-504,259],[-100,193],[-58,356],[520,91],[376,140],[151,-73],[241,46],[-293,364],[230,228],[352,75],[-9,117],[246,-67]]],"transform":{"scale":[0.004339064160663866,-0.0048000480004800035],"translate":[263.048961498887,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/ne.json b/src/onegov/election_day/static/mapdata/2025/ne.json new file mode 100644 index 0000000000..863bd391ee --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/ne.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":6404,"properties":{"id":6404,"name":"Boudry"},"arcs":[[-1,-2,-3,-4,-5,-6]]},{"type":"Polygon","id":6408,"properties":{"id":6408,"name":"Cortaillod"},"arcs":[[-7,-8,1]]},{"type":"Polygon","id":6413,"properties":{"id":6413,"name":"Rochefort"},"arcs":[[-9,-10,-11,-12,-13,-14,4]]},{"type":"Polygon","id":6416,"properties":{"id":6416,"name":"Milvignes"},"arcs":[[5,13,-15,-16]]},{"type":"Polygon","id":6417,"properties":{"id":6417,"name":"La Grande Béroche"},"arcs":[[-17,-18,2,7]]},{"type":"Polygon","id":6421,"properties":{"id":6421,"name":"La Chaux-de-Fonds"},"arcs":[[-19,-20,-21,-22,-23]]},{"type":"Polygon","id":6422,"properties":{"id":6422,"name":"Les Planchettes"},"arcs":[[-24,19,-25]]},{"type":"Polygon","id":6423,"properties":{"id":6423,"name":"La Sagne"},"arcs":[[22,-26,10,-27,-28,-29]]},{"type":"Polygon","id":6432,"properties":{"id":6432,"name":"La Brévine"},"arcs":[[-30,-31,-32,-33,-34]]},{"type":"Polygon","id":6433,"properties":{"id":6433,"name":"Brot-Plamboz"},"arcs":[[-35,-36,26,9]]},{"type":"Polygon","id":6434,"properties":{"id":6434,"name":"Le Cerneux-Péquignot"},"arcs":[[33,-37,-38,-39]]},{"type":"Polygon","id":6435,"properties":{"id":6435,"name":"La Chaux-du-Milieu"},"arcs":[[-40,29,38,-41]]},{"type":"Polygon","id":6436,"properties":{"id":6436,"name":"Le Locle"},"arcs":[[40,37,-42,24,18,28,-43]]},{"type":"Polygon","id":6437,"properties":{"id":6437,"name":"Les Ponts-de-Martel"},"arcs":[[42,27,35,-44,30,39]]},{"type":"Polygon","id":6451,"properties":{"id":6451,"name":"Cornaux"},"arcs":[[-45,-46,-47]]},{"type":"Polygon","id":6452,"properties":{"id":6452,"name":"Cressier (NE)"},"arcs":[[-48,-49,-50,46,-51,-52]]},{"type":"Polygon","id":6455,"properties":{"id":6455,"name":"Le Landeron"},"arcs":[[-53,-54,48,-55]]},{"type":"Polygon","id":6456,"properties":{"id":6456,"name":"Lignières"},"arcs":[[-56,-57,-58,52]]},{"type":"Polygon","id":6458,"properties":{"id":6458,"name":"Neuchâtel"},"arcs":[[51,-59,-60,14,12,-61,-62]]},{"type":"Polygon","id":6487,"properties":{"id":6487,"name":"Val-de-Ruz"},"arcs":[[-63,60,11,25,21,-64,56]]},{"type":"Polygon","id":6504,"properties":{"id":6504,"name":"La Côte-aux-Fées"},"arcs":[[-65,-66,-67]]},{"type":"Polygon","id":6511,"properties":{"id":6511,"name":"Les Verrières"},"arcs":[[-68,65,-69]]},{"type":"Polygon","id":6512,"properties":{"id":6512,"name":"Val-de-Travers"},"arcs":[[67,-70,31,43,34,8,3,17,-71,66]]},{"type":"MultiPolygon","id":6513,"properties":{"id":6513,"name":"Laténa"},"arcs":[[[58,50,45,-72]],[[61,62,55,54,47]],[[-73]]]}]}},"arcs":[[[66875,30378],[11,391],[-74,362],[74,439],[-19,213],[95,513],[70,162],[134,737],[145,171],[40,353]],[[60397,29435],[71,174],[478,860],[251,390],[81,62],[365,61],[271,322],[194,77],[-19,192],[192,48],[147,162],[444,631],[276,294],[376,63],[619,-364],[16,184],[161,-129],[2049,-957],[207,-246],[299,-881]],[[48555,30259],[30,-443],[-213,-845],[-8,-131],[586,-158],[177,79],[218,-58],[727,358],[459,596],[287,299],[65,1],[240,362],[267,15],[143,115],[155,-35],[172,110],[96,383],[157,206],[210,-14],[157,177],[34,-88],[280,305],[297,208],[102,292],[230,-151],[112,172],[51,-608],[138,-516],[-68,-168],[28,-265],[420,-593],[217,-144],[254,-350],[270,-260],[775,-589],[141,-42],[960,213],[136,474],[195,-130],[557,-32],[186,205],[122,417],[166,130],[231,47],[462,-91],[298,-112],[-31,-102],[817,-439],[163,317],[153,-24],[221,83]],[[46689,33116],[757,-1023],[497,-960],[19,-119],[176,-271],[417,-484]],[[59430,38512],[-176,-248],[-210,108],[-192,-352],[-453,-460],[-251,-303],[-38,71],[-289,-429],[-28,-256],[-297,-351],[-206,-110],[-420,254],[-168,-18],[-175,-156],[-84,33],[-234,-467],[-727,200],[-365,192],[-312,257],[-334,-110],[-285,-15],[-44,-307],[-291,-50],[-174,121],[-94,-222],[97,-334],[-58,-270],[-312,-180],[-147,150],[-242,-32],[-397,-201],[-160,-161],[-273,-117],[-337,4],[-404,-409],[-325,-445],[-358,-162],[-165,-373],[-237,-244],[-488,-179],[-215,4],[-292,-150],[-219,-328],[-212,-500],[-253,-159],[-198,96],[-446,440],[-13,217],[-89,142],[-461,320],[-350,94],[-340,-1]],[[67351,33719],[-382,132],[-2,207],[-498,382],[-163,338],[-434,595],[-333,-487],[-313,-411],[-218,421],[-301,325],[-54,-364],[-264,-258],[-210,282],[-312,33],[-64,162],[-444,-451],[-203,184],[-70,-108],[-258,158],[-200,-148],[-304,835],[-146,54],[-131,194],[-307,-452],[-47,83],[-91,-266],[-202,-194],[-87,63],[104,185],[-227,143],[-329,897],[63,67],[-262,485],[-116,295],[123,154],[209,-76],[3,233],[-216,72],[-122,203],[-125,-42],[-191,163],[-217,84],[-290,454],[-91,-2],[-199,169]],[[62051,26347],[96,439],[188,366],[359,442],[121,237],[68,-2],[500,598],[59,-177],[284,141],[61,101],[216,-359],[138,150],[152,36],[-133,283],[213,310],[159,-99],[252,191],[373,-36],[187,297],[426,322],[332,341],[539,354],[226,6],[8,90]],[[60397,29435],[383,-26],[133,-69],[-362,-437],[269,-457],[-121,-155],[267,-650],[9,-204],[398,-192],[142,-310],[123,-495],[205,67],[208,-160]],[[46978,35313],[-739,-1600],[450,-597]],[[55428,52112],[-138,-412],[-149,-224],[-96,-475],[-75,-163],[-307,-454],[-136,-85],[-258,-463],[-125,-132],[-392,-857],[100,-369],[-178,27],[-51,268],[-108,6],[-257,-543],[57,-91],[-237,-306],[-55,18],[-252,-282],[-98,-194],[-350,423],[-415,-745],[-464,-707],[-100,170],[-102,-206],[-238,-308],[-582,-411],[-7,-53],[522,-1226],[1059,-2457],[834,-2120],[-155,-136],[-307,-151],[-835,-314],[-258,-299],[-332,-289],[-258,-142],[-189,-178],[-218,-288],[-152,-98],[-356,-454],[-146,-36],[-323,-271],[-179,-15],[-328,-140],[-154,-255],[-414,-494],[-207,-56],[-469,-493],[-220,-61],[-352,-258]],[[55467,52092],[-39,20]],[[62999,44337],[-60,412],[-134,304],[-262,-212],[-168,2],[-158,181],[-186,-40],[-108,287],[-213,128],[-127,353],[-218,155],[-436,488],[-748,733],[-258,-84],[-356,322],[65,247],[109,7],[25,152],[-137,123],[-514,175],[100,254],[-315,281],[-735,820],[-79,299],[-253,560],[-208,256],[-202,44],[-276,316],[-792,553],[-22,330],[-144,40],[-87,-278],[-635,547]],[[63193,42608],[-194,1729]],[[59430,38512],[-164,262],[351,349],[304,367],[193,147],[532,566],[748,307],[491,92],[207,111],[176,15],[98,-256],[113,-125],[138,90],[320,26],[430,192],[91,324],[23,531],[-165,446],[-123,652]],[[70591,40727],[-167,794],[-96,859],[-634,-392],[-595,-69],[-22,374],[-91,10],[-685,-328],[-609,-162],[-436,-473],[-267,-209],[-432,-127],[-222,106],[-57,-226],[-254,157],[-8,-149],[-178,-247],[-136,216],[-555,476],[-308,192],[-66,289],[-500,502],[-146,252],[-739,83],[-195,-47]],[[67351,33719],[85,681],[-88,813],[-82,583],[117,470],[27,427],[-165,576],[137,592],[13,238],[-89,173],[261,201],[65,-177],[418,345],[249,274],[115,483],[94,-52],[282,379],[-157,149],[35,136],[183,223],[187,120],[181,-52],[316,249],[205,-45],[728,414],[123,-192]],[[43954,27713],[6,-250],[-75,-153],[-31,-318],[144,-460],[105,-195],[279,-200],[-444,-1665],[-365,-2207],[-163,-934],[24,-1310],[-171,-1779],[654,-227],[858,-1100],[771,-894],[1266,-1382],[-117,-1227],[-225,-2007],[303,-61],[95,-371],[-106,-362],[-92,-984],[-66,-129],[-172,-601],[-168,-884],[-141,-342],[-281,-288],[-129,-754],[-99,-336],[118,-141],[194,364],[563,594],[261,318],[88,-62],[1529,-226],[190,-168],[519,-54],[102,550],[12,243],[138,442],[93,-99],[-102,-263],[95,73],[46,198],[-59,117],[261,455],[60,-10],[297,686],[-30,249],[53,314],[309,621],[79,303],[155,846],[211,386],[230,289],[107,451],[68,-87],[149,179],[155,463],[286,-55],[108,79],[222,-381],[74,160],[39,339],[199,104],[143,-109],[276,545],[88,5],[18,208],[152,309],[163,670],[-33,60],[426,434],[151,191],[118,336],[107,-29],[65,171],[-30,192],[69,150],[29,318],[130,248],[332,224],[132,201],[241,139],[200,320],[271,572],[222,249],[235,403],[348,745],[143,240],[299,749],[406,345],[232,125],[100,-25],[219,136],[104,-52],[248,128],[105,364],[373,431],[-36,65],[466,708],[157,120],[83,-277],[198,-104],[-51,464],[262,158],[406,95],[-14,64],[354,254],[243,427],[146,107],[450,-114],[503,-307],[94,151],[171,809],[-32,285],[136,879]],[[48555,30259],[-509,-55],[-1238,-384],[-691,94],[-709,-238],[-235,-47],[-313,-128],[-151,12],[-168,-104],[-584,-204],[-292,-265],[-82,-308],[122,-383],[249,-536]],[[50876,75797],[94,-100],[-114,-244],[507,-873],[-176,-253],[90,-162],[43,-266],[371,-991],[115,-481],[100,-84],[135,-686],[55,-109],[304,187],[161,-307],[-69,-304],[255,-143],[248,103],[291,-601],[244,37],[288,-496],[167,-89],[66,-198],[-102,-152],[102,-21],[-90,-533],[-44,-87],[166,-75],[-154,-569],[-38,-485],[94,-243],[-86,-60],[274,-265]],[[55209,87892],[378,-745],[428,-428],[347,-659],[609,-817],[60,-1727],[-94,-1068],[-634,-263],[-871,-928],[-427,-163],[23,-151],[-556,-191],[-232,-205],[-1420,-1944],[53,-120],[-326,-147],[-492,-524],[-523,-522],[-121,178],[-179,-244],[276,-478],[-188,-197],[-243,-160],[-114,-202],[63,-58],[-150,-332]],[[66463,74523],[242,2263],[288,1827],[248,1507],[861,1083],[547,649],[597,3406],[255,1595],[122,667],[248,1503],[-413,913],[-178,610],[-538,1155],[-172,711],[-526,1342],[-665,1661],[-138,613],[-228,502],[-238,699],[-566,1572],[-431,1162],[-223,36],[-277,-146],[9,-295],[-444,-831],[-587,-822],[-224,-665],[-29,-163],[-233,-205],[-177,-23],[-297,-141],[-208,-153],[-308,-77],[-239,-210],[-105,-603],[38,-411],[-89,-201],[-135,-5],[-170,-189],[-726,-605],[-330,-381],[-171,115],[-139,-17],[-190,-336],[-230,-777],[-161,-307],[-303,-270],[-302,-145],[-169,-196],[-166,-291],[-346,-891],[-282,-248],[-280,-11],[-495,94],[-149,-76],[-130,-300],[-55,-822],[-120,-319],[-226,-183],[-440,-278],[-239,-112],[-200,-29],[-149,87],[-230,-49],[-347,-409],[-296,-211]],[[63290,68696],[934,1262],[714,1770],[610,830],[915,1965]],[[54173,67247],[779,1482],[237,552],[327,333],[323,16],[-75,152],[115,85],[-102,199],[558,116],[107,55],[420,453],[336,263],[28,-80],[233,74],[372,25],[191,112],[-59,371],[624,656],[-81,168],[471,492],[88,-163],[903,945],[611,786],[293,-692],[1434,-3515],[984,-1436]],[[55209,87892],[-429,-268],[-1095,-613],[-383,-102],[-153,-105],[-216,-429],[-222,-249],[-196,-75],[-299,106],[-323,-6],[-478,-103],[-255,-106],[-320,-226],[-353,-340],[-179,-90],[-325,-368],[-239,-132],[-363,-581],[-266,-119],[-110,-129],[-378,-848],[-132,-136],[-134,-262],[-177,-185],[-238,-85],[-355,144],[-287,-101],[-65,-181],[-23,-325],[102,-728],[203,-693],[131,-189],[525,-1040],[-16,-318],[54,-177],[-38,-344],[-86,-163],[-116,-472],[-93,-728],[-366,-353],[-93,-196],[-354,-170],[-365,-57],[-211,-149]],[[46493,76201],[2743,343],[546,-406],[835,-466],[145,-137],[114,262]],[[55467,52092],[99,222],[761,1308],[1151,1712],[677,1245],[291,605],[337,1468],[159,235],[147,530],[283,489],[36,-20],[388,1161],[59,81],[388,899],[123,376],[298,548],[188,426],[190,577],[421,710],[264,406],[586,1101],[230,598],[385,852],[217,718],[145,357]],[[53218,53561],[411,-298],[79,46],[198,-282],[80,103],[133,-208],[255,-250],[290,-171],[405,-178],[359,-211]],[[48940,56817],[820,-635],[1099,-924],[672,-461],[807,-615],[880,-621]],[[54173,67247],[80,-162],[-238,-94],[-200,-447],[-172,-1462],[-37,-482],[-95,-488],[-321,-620],[-82,-480],[-273,78],[-58,-280],[-64,17],[-78,-424],[-309,61],[-60,-77],[-33,-420],[-337,-663],[0,-100],[-221,-441],[-17,-246],[-309,-313],[-492,-280],[-316,-300],[-306,-340],[-235,-371],[-472,-488],[-49,108],[-285,-271],[-30,-152],[-428,-374],[357,-863],[-153,-56]],[[35789,40112],[-1537,3666],[-311,2510],[162,133],[-435,924],[113,108],[-295,626]],[[35202,39349],[587,763]],[[8195,38167],[420,-1004],[441,-1239],[606,-930],[270,-554],[903,-1200],[1603,-379],[1594,-987],[907,-548],[795,-532],[217,-228],[228,55],[603,488],[890,522],[502,89],[107,-80],[1556,-122],[1492,426],[1242,581],[3087,61],[668,434],[559,659],[345,474],[1646,1028],[2231,372],[351,-784],[420,448],[146,231],[444,517],[513,491],[982,1294],[233,427],[1006,1172]],[[24353,45297],[-278,-208],[-97,-161],[-396,-290],[-403,-478],[-727,-721],[-456,-207],[-14,-181],[-427,-383],[-198,-115],[-504,-149],[-271,-237],[-152,-54],[-346,-295],[-164,-87],[-226,39],[-456,-135],[-765,-358],[-2407,-1349],[-393,-49],[-1019,-307],[-245,-149],[-380,85],[-385,-184],[-388,-135],[-240,-128],[-542,-393],[-528,-543],[-328,-220],[-105,-17],[-418,-332],[-1245,2690],[-87,-64],[-1031,-1462],[-537,-553]],[[33486,48079],[-2541,-2389],[-2008,-1338],[46,-554],[-376,-117],[-430,-487],[36,-579],[-108,-203],[-1387,1228],[-1017,706],[-1348,951]],[[42962,37392],[584,-163],[1150,-1386],[134,-222],[1115,-1076],[263,301],[540,275],[230,192]],[[53218,53561],[-160,-44],[-263,-202],[-980,-1439],[-115,-137],[-1154,-1087],[-161,-220],[-155,-407],[-96,-693],[-112,-241],[-153,-85],[-476,-98],[-207,-329],[-68,-541],[-191,-245],[-186,-81],[-176,-376],[-393,-201],[-138,-180],[-157,-341],[-230,-28],[-90,-294],[-64,-3],[37,-362],[-114,-115],[-12,-179],[82,-73],[-103,-123],[-119,-344],[-410,-759],[-74,-366],[-218,22],[-112,202],[-203,-64],[-95,-121],[-6,-208],[-89,45],[44,-433],[-494,-406],[-77,-325],[-316,-473],[-466,-266],[-150,-370],[-363,-145],[-344,-453],[-318,-280],[-84,-233],[287,-402],[-82,-599],[-222,-763],[-510,-1304]],[[40827,60213],[-363,-483],[-294,-59],[-573,70],[-281,86],[-517,-40],[-432,-202],[-317,-201],[-638,-306],[-285,-247],[-193,-231],[-443,-371],[-245,-141],[-560,-550],[-438,-389],[-202,-242],[-287,-245],[-620,-1076],[-240,-491],[-817,-2430],[-189,-994],[-176,-597],[-267,-676],[-615,-1443],[-1043,-1457],[-334,-243],[-584,-307],[-340,-379],[-446,-431],[-173,-97],[-375,-440],[-139,-122],[-624,-24],[-160,-143],[-363,-110],[-310,118],[-415,-41],[-147,42],[-94,200],[-474,68],[-152,-35],[-4,248],[-573,-40],[-470,-176],[-42,-113],[-220,-176]],[[42712,57874],[-501,663],[-105,223],[-89,-39],[2,179],[-183,24],[-527,754],[-482,535]],[[33486,48079],[136,146],[1383,826],[924,567],[401,173],[324,278],[1807,1380],[2032,969],[-196,689],[1689,1675],[1033,376],[898,293],[1567,588],[-1012,573],[-772,398],[-604,508],[-384,356]],[[35789,40112],[219,381],[805,1054],[279,280],[602,1148],[1253,751],[1071,487],[376,192],[1681,1561],[563,497],[854,1204],[962,2088],[303,1279],[359,487],[401,656],[653,1189],[580,722],[1125,1062]],[[47875,55150],[-748,1316],[-1287,1335],[-1048,230],[-969,-101],[-1111,-56]],[[46493,76201],[-315,-10],[-214,-57],[-365,179],[-442,616],[-227,-101],[-135,-187],[-82,-321],[-217,-161],[-246,13],[-464,-87],[-395,-251],[-207,-370],[70,-91],[-71,-176],[-249,-142],[-347,-497],[-117,101],[-99,-128],[-82,-343],[-641,-188],[-148,-122],[-11,-270],[132,-229],[150,-95],[322,-77],[147,-284],[-42,-264],[-287,-453],[-42,-258],[198,-441],[-188,-253],[-190,-2],[-119,-120],[-335,-1050],[-164,-131],[-478,-124],[-158,-98],[-381,-2],[-187,-311],[-106,-400],[355,-611],[64,-385],[134,-325],[83,82],[-46,141],[126,107],[294,-392],[199,-335],[-11,-289],[137,-327],[204,-228],[212,-13],[130,157],[156,-40],[372,-393],[178,103],[191,-638],[24,-221],[161,-395],[155,-196],[324,-126],[424,-230],[256,-42],[122,-86],[-68,-266],[-1173,-978],[-413,-962],[-460,-198],[-655,-1116],[-409,-601]],[[47875,55150],[1065,1667]],[[35202,39349],[135,-669],[793,-13],[1849,1196],[755,947],[838,-70],[3390,-3348]],[[91695,54969],[-22,801],[9,776],[23,275],[91,405],[123,302],[398,799]],[[88640,61023],[-272,-247],[-260,-127],[-302,-352],[-229,-156],[-237,-297],[57,-594],[-22,-207],[-201,-328],[-232,-847],[0,-577],[-84,-589],[-52,-152],[-195,-185],[-228,-585],[321,-737],[83,-79],[293,67],[453,-658],[275,195],[242,-236],[105,-268],[350,504],[267,-379],[406,592],[46,-90],[234,607],[-213,205],[373,467],[-32,122],[313,546],[421,394],[334,154],[241,-667],[105,-650],[-37,-635],[66,-23],[-112,-510],[58,-74],[180,312],[540,30]],[[92317,58327],[-76,75],[47,826],[-54,5],[-640,706],[-619,978],[-391,-211],[-91,140],[-108,-137],[-148,270],[37,74],[-255,323],[-592,-14],[-258,-258],[-529,-81]],[[91169,69011],[-311,-325],[-320,-461],[-193,-145],[-80,138],[-111,-179],[-136,-433],[-22,-434],[-181,16],[-20,-433],[105,-107],[9,-322],[-96,-273],[127,-115],[119,-488],[-24,-239],[-364,-527],[-380,-445],[-153,-89],[-354,-314],[-149,-339],[-191,78],[-260,21],[-105,165],[-7,-163],[-142,55],[-477,729],[-38,421],[104,592],[66,528],[-14,143],[-194,-1],[-395,241],[-210,220],[-191,-253],[-164,-361],[-77,-309],[-233,-609],[-694,-1254]],[[94774,61067],[-143,433],[-93,400],[-192,591],[-47,701],[-100,136],[48,110],[379,77],[-551,962],[-102,326],[457,232],[-105,722],[-164,-55],[-30,228],[-268,-30],[-178,348],[-53,274],[-180,413],[-791,599],[-162,-21],[-149,87],[-97,-74],[-537,1275],[-334,70],[-213,140]],[[92317,58327],[157,310],[315,446],[1315,1417],[329,340],[341,227]],[[85335,63681],[37,-64],[72,-631],[188,-559],[284,-457],[144,-57],[408,-329],[-22,-56],[323,-233],[260,-248],[252,-63],[202,146],[315,90],[262,11],[190,78],[235,-243],[155,-43]],[[85413,63740],[-78,-59]],[[98406,71360],[-354,430],[-279,144],[-90,210],[-261,10],[-405,-573],[-328,-23],[-1390,-1322],[-294,294],[-47,204],[-94,29],[-639,580],[-284,323],[-180,259],[-407,439],[-740,873],[-397,578]],[[94774,61067],[1000,327],[414,30],[426,176],[568,623],[337,511],[206,218],[244,143],[306,286],[256,349],[-126,38],[-127,238],[-56,-59],[-136,258],[-98,-191],[-124,77],[-174,508],[63,244],[251,305],[-15,139],[128,197],[94,2],[236,173],[678,414],[228,181],[323,91],[323,-46],[-107,429],[-182,457],[-188,260],[-16,150],[-165,138],[-170,-33],[-47,210],[130,205],[59,257],[-358,-14],[-52,223],[-18,492],[97,809],[-6,401],[-96,375],[-205,270],[-58,182],[-211,250]],[[92217,73815],[-464,-663],[-556,-1451],[-151,-352],[-26,-445],[-246,40],[-9,-128],[-239,13],[9,-969],[147,-201],[159,-57],[172,-187],[156,-404]],[[88706,77358],[743,71],[1526,-2014],[1242,-1600]],[[90311,82864],[-119,-140],[-59,-264],[-206,-612],[-419,-904],[-256,-1746],[-546,-1840]],[[98406,71360],[191,252],[1343,1504],[-31,1310],[-637,1278],[-1046,2070],[-1323,688],[-563,362],[-929,50],[-280,454],[-615,807],[-293,423],[-588,470],[-642,606],[-84,202],[-743,-695],[-1069,-976],[-334,1171],[-452,1528]],[[82044,49261],[-165,253],[109,116],[-361,1084],[-213,486],[-164,520],[-15,579],[-209,859],[-1000,1776],[136,49],[791,1054],[119,95],[334,482],[53,334],[-46,223],[479,469],[478,791],[255,726],[266,277],[435,754],[182,495],[36,438],[206,-114],[357,452],[338,707],[264,366],[396,855],[58,168],[172,126]],[[70591,40727],[674,231],[100,342],[503,191],[45,-185],[97,85],[408,105],[183,118],[296,339],[326,543],[219,118],[-40,174],[74,209],[179,185],[456,335],[236,243],[270,199],[178,-137],[185,182],[29,286],[253,80],[297,-193],[51,-233],[328,12],[356,336],[137,-32],[189,204],[17,-153],[224,-45],[-11,150],[241,52],[290,376],[601,480],[699,328],[128,-32],[76,188],[333,323],[109,166],[199,21],[190,-61],[215,138],[153,410],[185,207],[-55,281],[33,146],[-84,210],[111,232],[399,367],[167,276],[282,205],[63,-11],[346,378],[144,-2],[179,180],[190,-13]],[[84686,67629],[-237,-418],[-292,-996],[-585,-1902],[-371,-1604],[-536,-1999],[-648,-1479],[-443,-758],[-360,-566],[-1353,-609],[-826,-578],[-503,-558],[-453,-565],[-520,-565],[-404,-707],[-351,-349],[-154,-197],[-709,-694],[-1227,-1259],[-780,-577],[-565,-723],[-72,490],[188,726],[116,582],[291,741],[-367,643],[-492,329],[-136,401],[-108,169],[95,255],[124,95],[107,215],[1,167],[131,166],[34,164],[-77,150],[60,134],[208,178],[10,400],[-278,294],[-220,512],[-83,-496],[-61,-176],[-211,-913],[-279,-1042],[143,-691],[-166,-416],[-302,278],[-401,307],[-176,-35],[-760,-264],[-226,-123],[-348,-472],[-1314,-642],[-140,-335],[104,-160],[137,-610],[-179,-307],[-153,-617],[36,-250],[-70,-208],[-360,-710],[299,-100],[-409,-191],[-461,-311],[-134,-358],[-357,-597],[-465,-396],[-298,-328],[-307,-116],[-612,-371],[-889,-440],[61,-250],[-407,-522],[225,-738],[4,-200],[-318,-3],[-78,90],[-256,-278],[-33,100],[-237,-256],[-447,37],[-57,110]],[[85413,63740],[-104,1148],[-435,2111],[-188,630]],[[84686,67629],[267,763],[531,838],[549,1285],[295,277],[251,503],[343,1335],[639,1774],[462,691],[683,2263]],[[90311,82864],[376,707],[258,414],[573,1217],[149,55],[532,787],[305,383],[325,351],[-261,568],[-1087,284],[-388,-122],[-23,-123],[-426,-753],[-449,2],[-537,-68],[-489,31],[-346,-159],[-457,-76],[-50,187],[-173,113],[-209,20],[-246,-234],[-3,-179],[-223,-126],[-444,-97],[-8,-174],[-341,-438],[-259,-189],[13,-76],[-288,-160],[-641,-255],[-312,-168],[-506,-177],[-605,-171],[-948,-231],[-211,-117],[-119,80],[-250,-146],[-418,-136],[-316,-56],[-200,14],[-897,-155],[-333,-143],[-328,-65],[-386,-177],[-187,39],[-365,-125],[-157,-108],[-67,115],[-159,-159],[-596,-406],[-179,-208],[-352,-245],[-91,182],[-451,-313],[-335,322],[-649,909],[-498,-1084],[-782,-867],[-524,-399],[-353,-413],[-637,-378],[-431,-292],[-518,-407],[-1194,-975],[-306,-219],[-516,-458],[-339,-344],[29,-49],[-299,-295],[-792,-622],[-171,-74],[-218,-185],[-205,-47],[-591,-539],[-709,-530],[-36,27],[-524,-436]],[[4470,9205],[-317,-4799],[-199,-2859],[813,-163],[169,-951],[638,-233],[1738,-200],[714,380],[1011,504],[1188,609],[506,273],[1527,739],[1373,537],[309,429],[342,238]],[[9586,11138],[-1740,-615],[-1737,-712],[-1639,-606]],[[14282,3709],[-1075,1131],[-380,538],[-291,499],[-517,718],[-649,673],[-266,463],[-640,1370],[-878,2037]],[[9586,11138],[888,2311],[528,1351],[16,1050],[1268,516],[-146,441],[-22,245],[-152,619],[-390,-199],[-158,662],[-42,554],[-460,27],[-366,83],[-59,1275],[-41,19],[-77,673],[-67,1310],[-52,1867],[234,565],[318,147],[-343,2674],[-368,-336],[-182,-279],[-249,-150],[-365,1008],[90,165],[-88,298],[-93,-124],[-310,722],[-238,390],[63,138],[-75,162],[57,215],[269,312],[-127,229],[-107,371],[-287,-249],[-56,146],[138,856],[140,-228],[299,235],[-118,289],[-74,-80],[-366,695],[-115,313],[47,174],[-145,306],[-121,-114],[-437,395],[-83,-100],[-283,453],[-193,-358],[-544,544],[-328,515],[-206,250],[-205,-548],[-129,-251]],[[5674,33692],[-472,-612],[-186,-602],[-202,-353],[-253,-315],[-127,-318],[-176,-722],[-170,-294],[-222,-227],[-381,-640],[-242,-224],[-36,-206],[-271,-295],[-326,-555],[-488,-605],[-841,-721],[-303,-303],[-193,-58],[-460,-370],[-325,-212],[467,-2234],[492,-665],[369,-638],[1394,-3091],[1048,-2252],[549,-1811],[444,-1501],[-157,-2638],[-136,-2025]],[[8195,38167],[-299,-403],[-395,-620],[-540,-754],[-548,-1040],[-381,-754],[-358,-904]],[[14282,3709],[177,109],[293,405],[550,1102],[190,268],[372,661],[203,4],[727,433],[136,50],[249,239],[511,821],[365,368],[447,98],[207,-64],[128,166],[350,76],[222,162],[203,234],[418,317],[844,798],[343,282],[336,231],[1967,1179],[874,2],[551,-269],[250,24],[1208,939],[392,190],[857,504],[1902,-92],[1075,2046],[794,1529],[976,1899],[227,1302],[48,126],[675,517],[367,315],[129,232],[1248,1178],[851,826],[1748,1071],[630,478],[819,459],[2827,1666],[1189,723],[797,400]],[[82044,49261],[245,367],[170,108],[72,170],[60,-113],[182,137],[193,272],[67,246],[196,137],[124,2],[-26,215],[159,-64],[179,161],[61,-97],[218,-66],[269,-241],[83,-176],[95,101],[258,-95],[-98,149],[183,177],[58,157],[141,-50],[125,107],[289,-145],[55,-207],[222,-270],[-22,-154],[117,3],[-107,-193],[36,-197],[337,-492],[-104,-66],[96,-205],[98,273],[34,-217],[284,73],[204,-181],[180,45],[170,-141],[127,12],[11,-207],[208,-219],[304,-207],[396,-50],[-5,89],[313,47],[67,-150],[16,241],[178,296],[335,61],[75,262],[253,20],[111,-85],[133,113],[469,-306],[-118,-3],[-154,130],[18,-601],[-836,-1433],[146,-164],[330,509],[206,420],[197,170],[121,216],[163,142],[345,595],[255,153],[-112,419],[-67,79],[641,1041],[164,294],[162,429],[114,462],[204,1047],[31,589],[-53,1767]],[[92695,41041],[-87,237],[-395,-21],[-1221,504],[-18,-102],[1748,-720],[-27,102]]],"transform":{"scale":[0.006810477192991629,-0.004800048000480005],"translate":[139.47954558901506,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/nw.json b/src/onegov/election_day/static/mapdata/2025/nw.json new file mode 100644 index 0000000000..bf96e323bf --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/nw.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":1501,"properties":{"id":1501,"name":"Beckenried"},"arcs":[[-1,-2,-3,-4,-5,-6,-7]]},{"type":"Polygon","id":1502,"properties":{"id":1502,"name":"Buochs"},"arcs":[[-8,-9,-10,0]]},{"type":"Polygon","id":1503,"properties":{"id":1503,"name":"Dallenwil"},"arcs":[[-11,-12,-13,-14,-15]]},{"type":"Polygon","id":1504,"properties":{"id":1504,"name":"Emmetten"},"arcs":[[3,-16]]},{"type":"Polygon","id":1505,"properties":{"id":1505,"name":"Ennetbürgen"},"arcs":[[-17,1,9,-18,-19]]},{"type":"Polygon","id":1506,"properties":{"id":1506,"name":"Ennetmoos"},"arcs":[[-20,-21,-22,10]]},{"type":"Polygon","id":1507,"properties":{"id":1507,"name":"Hergiswil (NW)"},"arcs":[[-23,-24]]},{"type":"Polygon","id":1508,"properties":{"id":1508,"name":"Oberdorf (NW)"},"arcs":[[6,-25,12,-26,7]]},{"type":"Polygon","id":1509,"properties":{"id":1509,"name":"Stans"},"arcs":[[17,8,25,11,21,-27]]},{"type":"Polygon","id":1510,"properties":{"id":1510,"name":"Stansstad"},"arcs":[[18,26,20,-28,23,-29]]},{"type":"Polygon","id":1511,"properties":{"id":1511,"name":"Wolfenschiessen"},"arcs":[[13,24,5,-30]]}]}},"arcs":[[[65193,85629],[-724,-4662],[-468,-810],[31,-665],[-95,-489],[-410,-1000],[-294,-954],[-307,-524],[31,-185],[-284,-121],[-236,-264],[-41,-284],[181,-228],[-311,-331],[-64,-292],[-164,-364],[-462,-628],[-334,-357],[-124,-213],[-256,-59],[-21,-142],[-178,-138],[-21,-203],[-251,-555],[-244,-203],[-389,-636],[-367,-829],[-162,-239]],[[69245,85955],[-4052,-326]],[[84441,84361],[-6354,-1450],[-8842,3044]],[[76844,59518],[-365,1789],[55,447],[-52,731],[183,457],[-10,269],[114,516],[-222,646],[-1718,169],[-8,230],[169,433],[-64,197],[199,506],[186,296],[349,408],[185,300],[243,952],[61,122],[-475,338],[-160,329],[-221,681],[-85,655],[-259,1023],[42,102],[816,271],[297,252],[-86,529],[109,781],[1061,376],[717,210],[362,151],[404,438],[116,209],[-43,137],[12,536],[-47,468],[-211,682],[343,44],[340,-147],[403,-59],[681,21],[655,131],[-93,125],[611,364],[-5,93],[304,112],[162,-35],[-85,-153],[224,-92],[222,-252],[259,220],[451,241],[204,19],[4,111],[779,161],[127,140],[703,538],[620,363],[422,133],[371,350],[202,89],[154,279],[-209,356],[-38,366],[-79,127],[-1789,4562]],[[69400,53910],[642,233],[335,-166],[816,443],[1010,387],[108,122],[780,131],[132,110],[304,66],[277,171],[346,94],[185,554],[135,137],[463,702],[40,399],[90,310],[84,1390],[304,531],[474,-33],[544,51],[375,-24]],[[64611,61114],[385,-26],[204,-436],[51,-224],[277,-461],[482,-243],[320,-278],[660,-1077],[356,-762],[24,-218],[-41,-601],[624,-366],[172,-180],[128,-272],[312,-995],[65,-385],[770,-680]],[[59229,70254],[328,-404],[155,-291],[157,-95],[582,-11],[51,-485],[-67,-347],[43,-230],[247,-53],[5,-660],[-32,-616],[178,-232],[1130,-778],[225,-187],[485,-52],[514,249],[357,-209],[418,-592],[514,-318],[494,1],[408,-106],[178,-596],[46,-344],[324,-262],[76,-142],[210,-34],[8,-114],[259,-240],[338,-980],[-32,-109],[-452,223],[-180,35],[-1001,485],[-320,77],[-227,-52],[1,-414],[-106,-226],[68,-1031]],[[47408,77956],[183,3],[1188,467],[977,413],[711,380],[1373,-2078],[522,-762],[688,-1063],[925,-1315],[342,-283],[18,-227],[250,-276],[360,-297],[234,-308],[232,-768],[-34,-204],[306,-455],[527,-580],[381,153],[514,-290],[356,-405],[342,-94],[551,64],[875,223]],[[47617,80920],[-209,-2964]],[[65193,85629],[-6318,91],[-2557,-1296],[-902,-771],[-271,-176],[-207,371],[-309,31],[-1924,-465],[-5088,-2494]],[[35891,64204],[-574,-266],[-24,-119],[-297,-17],[-705,-333],[-409,-84]],[[42801,66347],[-87,-213],[-360,-248],[-329,-96],[-538,18],[-256,-248],[-672,-95],[-414,135],[-632,-244],[-587,-183],[-174,-210],[-259,-143],[-161,-175],[-449,-57],[-401,-111],[-492,-231],[-490,53],[-609,-95]],[[49176,64205],[83,582],[206,488],[68,480],[-82,1161],[-852,-79],[-421,-68],[-415,-6],[-372,-134],[-419,-44],[-391,70],[-302,123],[-613,-9],[-879,33],[-619,287],[-475,-229],[-114,-143],[-414,-284],[-364,-86]],[[33950,47551],[248,141],[968,-152],[1879,293],[718,1008],[1376,1656],[238,206],[425,483],[433,869],[1024,447],[583,318],[270,652],[504,300],[1499,1047],[172,-180],[284,-77],[221,-323],[290,-142],[1254,1146],[509,-106],[272,5],[181,218],[-187,78],[89,257],[-114,285],[305,50],[374,-52],[291,-177],[305,-19],[441,-186],[370,105],[561,-126],[44,1007],[-54,908],[26,460],[73,350],[-46,967],[102,437],[237,476],[249,694],[78,634],[-46,279],[-200,508],[-29,563],[-325,424],[-451,350],[-97,139],[-118,434]],[[33882,63385],[459,-357],[136,-188],[292,-704],[-154,-267],[-128,-758],[-96,-149],[132,-265],[70,-428],[-162,-589],[-99,-65],[-323,-639],[269,21],[457,-287],[225,-81],[491,-1034],[-205,-984],[-23,-388],[-408,-1134],[-249,-218],[-82,-172],[-760,-606],[-83,-352],[26,-169],[-90,-321],[51,-193],[-137,-267],[133,-173],[16,-387],[155,-307],[69,-446],[219,-545],[66,-548],[-76,-370],[46,-487],[-57,-300],[30,-839],[-25,-563],[-117,-275]],[[76844,59518],[379,-7],[331,69],[235,-259],[381,59],[56,-54],[596,356],[477,-879],[337,-273],[294,-498],[226,-76],[291,76],[571,254],[347,8],[527,196],[425,252],[102,167],[297,129],[557,351],[383,46],[189,416],[786,418],[176,634],[87,507],[538,39],[529,-65],[229,41],[144,135],[767,76],[338,-16],[140,161],[335,-83],[308,38],[758,555],[423,42],[338,268],[412,79],[681,251],[209,123],[102,195],[515,276],[-2,354],[-66,82],[142,306],[331,302],[24,131],[347,537],[151,151],[-146,58],[-14,308],[153,286],[56,302],[-143,426],[-309,-81],[-184,286],[-146,367],[-151,546],[-244,266],[224,49],[1271,-318],[258,288],[676,-30],[604,15],[154,91],[204,274],[59,-368],[255,50],[467,240],[98,193],[-182,216],[-645,-75],[-71,133],[-15,414],[128,122],[98,536],[-87,230],[256,418],[-371,90],[430,778],[-104,65],[-35,374],[-358,1131],[-24,481],[68,553],[-18,666],[-54,352],[47,1084],[77,276],[-101,322],[-183,210],[-69,799],[408,89],[570,307],[179,467],[306,111],[118,428],[218,587],[188,255],[26,166],[212,443],[-252,1086],[1037,589],[311,119],[109,176],[286,200],[263,433],[293,679],[374,581],[159,69],[224,473],[210,297],[242,519],[-194,306],[-940,2537],[-7883,-4368],[-6539,1]],[[69245,85955],[756,4947],[184,5147],[-11549,3044],[-264,-6031],[62,-219],[1,-721],[-57,-190],[200,-257],[-396,-270],[-419,-1],[-589,-67],[-306,64],[-1232,82],[-365,-17],[-281,-77],[-396,57],[-277,159],[-192,24],[-352,249],[-146,-83],[-707,250],[-158,-36],[-309,153],[-462,-193],[-244,100],[-375,-87],[-705,43],[-496,297],[-313,82],[-231,-85],[-348,-243],[-238,-12],[-438,-135],[-412,-66],[-685,-325],[-652,-199]],[[46784,84578],[177,-323],[205,-175],[286,-387],[191,-377],[203,-251],[-27,-477],[-126,-1259],[-76,-409]],[[46854,91339],[-195,-43],[-269,-211],[-700,-252],[-495,-124],[-570,-91],[-317,-146],[-230,-215],[-424,-261],[1168,-788],[1308,-161],[971,19],[695,-1505],[-270,-689],[-136,-445],[-349,-596],[-378,-502],[121,-751]],[[25563,77110],[-766,-3186],[602,-963],[464,-435],[-392,-244],[-846,-609],[-113,-167],[-637,-405],[-279,-336],[-325,-178],[-383,-327],[-483,-622],[-91,-382],[-155,-267],[-287,-312],[-154,-375],[-557,-483],[-279,-364],[-80,-285],[-295,-573],[-82,-378],[-196,-162],[-61,-316],[-210,-285],[-76,-382],[419,-168],[336,-296],[417,-117],[614,-266],[453,-75],[230,-203],[853,-309],[279,-198],[-81,-161],[59,-225],[386,-343],[731,-499],[82,-116],[320,-117],[200,-151],[331,-73],[174,-113],[229,-366],[930,439],[198,-35],[517,-361],[527,248],[800,89],[429,76],[211,-15],[327,94],[159,147],[326,81],[739,358],[1810,454],[995,532]],[[34704,78082],[-896,-191],[-236,-203],[-280,-136],[-434,-37],[-879,-271],[-125,-138],[36,299],[-118,407],[-519,359],[-762,1116],[-3279,-1812],[-1649,-365]],[[35891,64204],[121,1571],[244,2331],[110,628],[-60,593],[12,292],[-100,686],[113,202],[-66,770],[-6,604],[54,22],[145,693],[120,148],[179,544],[-121,1281],[7,488],[-61,248],[67,242],[-577,251],[-878,266],[-490,2018]],[[32572,87423],[-4420,4204],[-2014,-560],[-3,-80],[-420,87],[-151,-74],[-724,31],[-350,-124],[-170,91],[-546,111],[-754,-123],[-541,72],[-452,-210],[-417,171],[-193,-37],[-273,-485],[55,-298],[-413,-137],[-435,37],[-485,-374],[-94,-192],[-636,32],[-800,139],[-675,256],[-390,222],[-278,422],[-280,260],[-1172,-229],[-212,87],[-466,-60],[-400,225],[-579,37],[-299,-103],[-375,89],[-1520,-786],[-446,-360],[-885,-512],[-137,-171],[-43,-369],[-189,-159],[-139,-269],[-846,-668],[-568,-772],[21,-314],[-1228,-584],[-531,448],[-227,328],[-329,331],[-173,280],[-63,347],[-173,172],[-281,420],[-625,-304],[-504,367],[-736,212],[-842,14],[-22,-277],[-199,-345],[-192,-539],[-499,-551],[5,-203],[-189,-148],[-172,-512],[-191,-337],[-370,-419],[-114,-504],[-259,-216],[-544,-618],[291,-768],[356,-247],[57,-254],[383,-283],[325,-597],[586,-314],[205,-33],[851,-676],[275,237],[358,-199],[285,60],[389,408],[635,63],[827,-289],[584,-47],[300,167],[517,118],[529,304],[310,288],[393,193],[1142,1077],[188,255],[351,244],[612,-244],[768,228],[302,29],[168,106],[232,-271],[-11,-267],[246,-367],[340,229],[280,-125],[573,55],[263,-46],[282,168],[220,46],[849,-98],[587,-233],[263,-292],[162,44],[701,-188],[232,-10],[134,-144],[284,28],[270,-302],[315,74],[348,-63],[334,140],[371,-117],[301,10],[319,95],[307,-7],[625,231],[141,226],[514,-84],[254,102],[189,-19],[341,141],[193,-55],[336,64],[356,-33],[208,98],[383,-188],[470,-110],[450,-184],[141,-157],[196,-45]],[[24986,82064],[870,-140],[101,107],[333,111],[863,-132],[640,12],[580,307],[405,97],[710,-72],[493,145],[54,106],[500,373],[55,196],[211,195],[179,-89],[768,-39],[-27,144],[851,4038]],[[49176,64205],[196,-18],[425,-183],[471,6],[586,-110],[693,156],[634,-27],[317,-114],[697,-14],[515,-292],[359,-47],[358,-196],[65,81],[512,-156],[315,-190],[602,-223],[414,-370],[156,-321],[-25,-207],[124,-278],[311,-305],[531,-267],[373,-136],[376,-286],[324,-180],[148,-11],[180,142],[241,-174],[988,-360],[167,-129],[294,77],[497,-138],[257,135],[420,90],[615,-252],[275,-13],[214,80],[213,212],[162,349],[389,380],[200,30],[495,-43],[351,211]],[[47408,77956],[-992,-402],[-383,-257],[-841,-667],[-638,-1260],[-262,109],[-686,-968],[-191,-374],[42,-257],[-174,-365],[-665,-301],[-226,-254],[359,-140],[-150,-123],[-264,-592],[-84,29],[-310,-685],[179,-323],[-146,-588],[51,-409],[156,-204],[26,-489],[263,-459],[113,-828],[-54,-989],[98,-504],[172,-309]],[[46784,84578],[-317,61],[17,91],[-298,-174],[-1122,-220],[-213,-68],[-295,15],[-303,-162],[-741,-188],[-569,-263],[-725,-436],[-518,-149],[-174,-306],[-242,-81],[-166,-167],[-521,-239],[-510,-403],[-636,-332],[-458,-8],[-223,-65],[-238,-257],[-697,-244],[-217,-194],[-79,-548],[-373,-625],[-547,238],[-177,334],[-624,-327],[-777,-315],[-29,-374],[-275,-652],[36,-325],[-69,-113]],[[24986,82064],[-66,-713],[514,-695],[104,-49],[152,-328],[90,-452],[304,-546],[-521,-2171]],[[46854,91339],[-782,888],[-41,335],[414,323],[140,305],[-327,5957],[-4292,852],[-9394,-12576]],[[33950,47551],[-102,-217],[-630,-639],[-515,-706],[-102,-748],[-64,-69],[140,-882],[-423,-577],[-339,-366],[-194,-357],[-336,-318],[140,-739],[348,-775],[-184,-581],[85,-540],[304,-531],[241,-175],[106,-422],[423,-90],[234,-446],[-161,-183],[111,-252],[-29,-190],[116,-290],[-3,-438],[59,-248],[-59,-490],[82,-332],[-1022,-1851],[-210,-1178],[218,-466],[-28,-430],[-457,-913],[-6,-149],[-182,-262],[-112,-561],[146,-406],[24,-450],[130,-433],[74,-599],[303,-149],[223,-255],[39,-317],[142,-169],[272,-851],[-70,-1683],[559,59],[270,-60],[208,-207],[-66,-236],[54,-278],[-278,-259],[2,-336],[99,-266],[8,-511],[-66,-358],[-491,-356],[-277,-297],[-334,-101],[-374,-206],[-218,-204],[-299,7],[-637,-354],[-338,-346],[-105,-232],[-289,-119],[-6,-190],[-235,-270],[31,-324],[233,-153],[183,-15],[-153,-417],[187,-292],[44,-240],[404,-410],[146,-31],[176,-265],[-21,-315],[453,-342],[475,-161],[591,-461],[109,-542],[349,-281],[169,-306],[303,-229],[205,-65],[316,-305],[444,-573],[260,-519],[597,-318],[550,-13],[77,-342],[118,-173],[-264,-345],[113,-379],[199,-310],[75,-282],[353,-66],[434,-245],[157,-152],[442,-674],[534,-263],[557,-165],[273,-338],[340,-180],[312,18],[737,-146],[259,-182],[349,-140],[584,-395],[310,-289],[632,-421],[181,-301],[585,-345],[-65,-494],[116,121],[408,30],[620,-349],[553,-408],[196,6],[81,-127],[404,-90],[201,-284],[252,-237],[-61,-129],[52,-269],[309,-217],[149,-248],[184,-135],[75,-254],[264,-481],[622,-359],[355,-248],[336,-104],[243,71],[226,-211],[716,-83],[1175,-2517],[5972,2844],[2787,-1555],[-23,1087],[-314,320],[-75,1080],[-155,359],[-173,61],[-140,312],[-111,509],[-132,110],[-317,512],[-259,104],[-261,381],[-50,332],[60,414],[-56,286],[-632,109],[-613,194],[-1031,-12],[-439,136],[-537,221],[-365,320],[-169,397],[-177,208],[-279,116],[-287,266],[-240,384],[-298,220],[-1014,-182],[-423,115],[-1701,2000],[-246,368],[-162,107],[-20,181],[-151,-71],[-21,154],[-241,259],[-476,211],[-320,70],[110,456],[559,761],[241,782],[144,293],[-105,281],[48,243],[-76,185],[-56,453],[-137,174],[-256,49],[-485,265],[-599,94],[-255,201],[-467,64],[-435,409],[-271,343],[-500,114],[-261,-122],[-342,-35],[151,305],[279,290],[87,235],[-46,405],[-74,147],[325,616],[244,351],[-112,161],[131,239],[4,256],[-131,125],[-76,253],[54,119],[-172,458],[89,173],[20,293],[-331,254],[-96,402],[-200,284],[28,74],[-163,525],[-249,296],[-214,159],[-182,348],[-78,411],[-217,281],[-78,508],[72,113],[185,612],[-225,450],[-87,377],[-62,590],[-24,1409],[-38,181],[-339,434],[100,517],[-144,277],[-151,568],[118,228],[135,73],[403,467],[68,454],[-47,1494],[60,293],[-79,926],[-355,-119],[-460,77],[-568,-42],[-557,52],[-129,243],[-449,650],[-168,320],[302,381],[53,193],[167,172],[157,462],[89,740],[217,-56],[197,66],[422,-18],[228,-66],[403,205],[-24,775],[152,487],[78,410],[355,559],[355,427],[190,128],[429,43],[420,-44],[1032,-165],[180,-188],[103,-470],[263,-156],[-187,-162],[-170,-29],[-136,-467],[450,-536],[0,-385],[817,-807],[-671,-778],[-446,-114],[-155,16],[-112,-217],[-369,-332],[-271,-625],[-634,-1226],[-55,-561],[142,-459],[58,-430],[-47,-268],[43,-237],[-150,-253],[-20,-226],[-259,-1010],[30,-386],[228,-233],[1006,2230],[794,1285],[836,-859],[349,321],[217,109],[45,361],[249,352],[660,228],[569,294],[405,627],[138,367],[422,619],[730,685],[218,238],[313,-163],[514,-84],[1220,551],[-37,357],[412,355],[559,604],[395,-160],[169,59],[395,588],[94,-353],[128,-170],[48,-313],[167,-535],[141,-250],[258,-143],[332,-290],[188,-49],[-27,-120],[206,-448],[179,-163],[-32,-524],[-69,-92],[142,-260],[135,-411],[-38,-566],[133,-300],[71,-394],[150,-235],[-257,-472],[-170,-140],[-42,-380],[225,-464],[377,-147],[395,-25],[335,-107],[93,43],[393,-95],[403,-31],[297,-265],[668,-145],[178,136],[624,119],[55,105],[531,282],[232,43],[190,223],[61,226],[675,227],[531,-173],[664,-13],[123,141],[290,111],[242,-8],[637,131],[61,55],[469,39],[1207,-134],[396,95],[533,251],[757,168],[330,-14],[111,112],[380,38],[225,-122],[259,157],[296,-91],[37,107],[389,25],[112,-104],[419,-100],[437,-24],[-52,167],[56,431],[-186,294],[-332,382],[-44,169],[63,301],[-298,407],[-64,172],[271,467],[119,89],[-83,392],[25,451],[92,311],[167,279],[335,1039],[-324,436],[-9,684],[-124,254],[-381,542],[-185,194],[-172,401],[-43,306],[30,437],[191,364],[1104,320],[225,205],[343,529],[330,259],[216,261],[141,11],[192,261],[90,-19],[475,382],[-612,1460],[-75,117],[-14,372],[-70,132],[61,237],[-255,133],[-270,239],[-117,299],[-415,596],[119,273],[21,301],[155,216],[-385,92],[-276,157],[-59,188],[-288,47],[-58,256],[-476,549],[-80,201],[-197,151],[-471,44],[-82,-74],[-806,-127],[-429,-12],[-509,162],[-227,177],[-109,287],[401,434],[27,185],[202,263],[225,84],[173,171],[-20,115],[370,351],[131,497],[133,322]]],"transform":{"scale":[0.004722232251307763,-0.004800048000480004],"translate":[243.89074855073753,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/ow.json b/src/onegov/election_day/static/mapdata/2025/ow.json new file mode 100644 index 0000000000..848be1a90a --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/ow.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":1401,"properties":{"id":1401,"name":"Alpnach"},"arcs":[[-1,-2,-3]]},{"type":"Polygon","id":1402,"properties":{"id":1402,"name":"Engelberg"},"arcs":[[-4]]},{"type":"Polygon","id":1403,"properties":{"id":1403,"name":"Giswil"},"arcs":[[-5,-6,-7,-8]]},{"type":"Polygon","id":1404,"properties":{"id":1404,"name":"Kerns"},"arcs":[[-9,-10,-11,2,-12]]},{"type":"Polygon","id":1405,"properties":{"id":1405,"name":"Lungern"},"arcs":[[7,-13,8,-14]]},{"type":"Polygon","id":1406,"properties":{"id":1406,"name":"Sachseln"},"arcs":[[6,-15,9,12]]},{"type":"Polygon","id":1407,"properties":{"id":1407,"name":"Sarnen"},"arcs":[[10,14,5,-16,0]]}]}},"arcs":[[[24408,79003],[183,-216],[428,-364],[261,-57],[926,-353],[10,-326],[-83,-42],[-27,-479],[27,-558],[129,-506],[279,-471],[248,-208],[115,-581],[-53,-251],[313,-100],[153,115],[108,195],[106,33],[193,-123],[194,95],[516,21],[255,78],[290,220],[202,228],[184,95],[245,-11],[330,137],[127,-5],[130,-164],[203,118],[157,-19],[162,-151],[254,214],[167,3],[261,-102],[448,140],[226,-113],[474,41],[84,43],[214,297],[314,27],[271,606],[193,293],[278,170],[340,-44],[447,217],[200,-48],[334,30],[322,245],[342,54],[281,-191],[218,18],[177,179],[277,66],[349,494],[145,7],[295,-386],[277,49],[142,-77],[133,218],[109,33],[753,-132],[495,-419],[255,-324],[-33,-50],[-10,-577],[225,-1020],[311,-414],[512,6],[55,-83],[206,23],[155,-143],[-529,-852],[435,-105],[155,120],[356,71],[112,-114],[303,-37],[688,-523],[161,265],[312,214],[219,-57],[240,233],[-81,65],[93,160],[299,223],[29,240],[130,214],[92,282],[156,224],[157,108],[146,241],[112,296],[64,320],[421,545],[127,44],[72,-144],[4,-292],[141,61],[356,20],[198,-208],[276,18],[277,-285],[292,32],[189,-229],[41,-157],[360,-216],[455,-356],[239,-45],[795,-334],[84,-196],[770,-487],[55,178],[166,203],[224,-141]],[[52649,79615],[58,417],[162,313],[46,345],[150,177],[63,414],[226,626],[61,311],[214,399],[268,289],[158,239],[118,409],[221,341],[118,292],[70,418],[370,680],[294,358],[248,194],[214,368],[488,443],[86,182],[649,665],[300,267],[-247,287],[-108,189],[-462,1053],[987,5857],[-234,597],[-68,495],[-132,388],[-65,24],[-173,380],[-221,379],[51,780],[-150,48],[-173,227],[-280,147],[-360,120],[-293,206],[-160,-107],[-272,35],[-258,-69],[-147,59],[-301,-163],[-106,31],[-194,-112],[-394,92],[-108,-248],[-479,-252],[-235,7],[-244,-103],[-231,-11],[-284,128],[-306,-158],[-217,74],[-241,-82],[-207,331],[-217,-31],[-103,158],[-178,11],[-537,205],[-124,-48],[-201,319],[-260,184],[-190,71],[-650,108],[-169,-52],[-216,-182],[-201,50],[-439,-60],[-215,136],[-260,-251],[-188,402],[8,292],[-178,296],[-128,-115],[-232,-33],[-589,-248],[-468,266],[-269,-267],[-144,-279],[-161,-140],[-46,-140],[-696,-940],[-273,-168],[-238,-315],[-405,-332],[-396,-130],[-230,-182],[-447,51],[-634,316],[-486,-68],[-254,-322],[-44,-125],[-218,-65],[-275,218],[-210,-260],[182,-437],[-113,-366],[-55,-578],[-398,-351],[-228,-76],[-715,54],[-513,101],[-347,-104],[-529,-71],[-459,-298],[-1085,-375],[-523,-107],[-750,-207],[-167,19],[-527,221],[-1038,514],[-1651,1321],[-969,-1088],[-185,-346],[-258,46],[-391,-25],[-182,58],[-297,-129],[-208,-226],[-184,-326],[-217,-18],[-209,-246],[-169,-12],[-754,-591],[-247,-20],[-359,-226],[-247,-33],[-487,-528],[-256,-326],[-327,-501],[-111,-218],[-197,-150],[-241,223],[-75,-177],[-184,-184],[-188,-74],[-23,-107],[180,-232],[-144,-227],[-396,-155],[-512,-359],[-131,-217],[117,-255],[-35,-231],[177,-41],[53,-179],[-73,-1294],[523,-1280],[1595,-2839],[184,66],[319,-676],[371,-1078],[-20,-335],[-210,-521],[-323,-386],[-59,-149],[-413,-312],[-171,27],[-185,-363],[-203,-566],[-113,-152]],[[50406,74302],[-54,187],[102,455],[221,537],[192,198],[166,-29],[66,202],[77,-32],[11,294],[244,623],[193,267],[134,356],[308,314],[133,693],[159,288],[176,218],[115,742]],[[99999,41480],[-330,229],[-161,293],[-302,272],[-149,294],[-95,666],[-395,715],[-155,88],[-247,388],[-1,380],[-140,272],[-295,-105],[-293,-257],[-397,-93],[-274,107],[-389,13],[-138,105],[-204,40],[-423,261],[-239,413],[-139,93],[-299,8],[-255,94],[-327,479],[-177,321],[-342,-102],[-212,-203],[-194,-387],[40,-94],[-87,-204],[-160,-171],[-214,-52],[-385,88],[-233,-36],[-185,68],[-335,27],[-321,109],[-86,113],[-298,-27],[-28,-117],[-227,99],[-198,-171],[-172,133],[-292,-42],[-85,-122],[-252,15],[-580,-183],[-409,-275],[-303,-104],[-925,147],[-359,-43],[-47,-60],[-488,-143],[-185,9],[-223,-121],[-94,-154],[-209,40],[-299,-26],[-407,189],[-517,-248],[-47,-248],[-146,-243],[-177,-47],[-407,-309],[-42,-115],[-478,-130],[-136,-148],[-512,158],[-228,290],[-308,34],[-302,103],[-71,-46],[-256,117],[-303,27],[-289,160],[-172,508],[32,415],[180,256],[147,413],[-115,257],[-54,432],[-102,328],[29,618],[-103,449],[-109,285],[53,100],[24,573],[-137,179],[-158,489],[21,131],[-144,54],[-254,317],[-198,156],[-108,274],[-128,584],[-36,342],[-98,187],[-73,386],[-302,-644],[-130,-64],[-302,176],[-428,-661],[-316,-389],[28,-390],[-325,-228],[-610,-374],[-394,92],[-239,178],[-167,-260],[-559,-749],[-323,-677],[-106,-401],[-311,-685],[-436,-322],[-505,-249],[-169,-334],[-81,-289],[25,-157],[-167,-119],[-267,-351],[-640,939],[-608,-1404],[-772,-2438],[-174,254],[25,265],[-48,157],[199,1104],[15,247],[115,277],[-33,258],[36,294],[-45,470],[-109,502],[43,613],[486,1341],[207,683],[283,363],[85,238],[119,-19],[342,125],[237,360],[277,491],[-626,882],[0,421],[-345,586],[96,298],[8,213],[131,31],[143,178],[-201,170],[7,162],[-86,353],[-138,205],[-791,181],[-321,47],[-329,-47],[-146,-140],[-272,-467],[-271,-611],[-61,-449],[-116,-531],[18,-847],[-214,-196],[-592,62],[-151,-71],[-166,61],[-69,-810],[-120,-505],[-128,-188],[-41,-211],[-231,-416],[129,-349],[344,-711],[98,-266],[428,-57],[435,46],[49,-56],[303,-28],[272,130],[28,-762],[33,-250],[-47,-321],[37,-1633],[-53,-497],[-497,-777],[111,-683],[110,-303],[-88,-467],[271,-572],[29,-198],[18,-1541],[48,-646],[66,-412],[173,-492],[-142,-668],[-55,-124],[60,-556],[166,-307],[60,-449],[139,-381],[164,-173],[191,-324],[125,-574],[-21,-81],[153,-311],[-8,-204],[81,-235],[254,-277],[-16,-321],[-68,-190],[132,-500],[-41,-130],[58,-276],[100,-137],[-3,-281],[-100,-261],[86,-175],[-284,-637],[-152,-421],[56,-161],[36,-443],[-67,-256],[-213,-318],[-117,-332],[263,38],[200,133],[383,-125],[207,-374],[334,-448],[357,-70],[195,-220],[460,-102],[371,-290],[196,-54],[105,-190],[43,-495],[58,-202],[-37,-266],[81,-307],[-111,-321],[-184,-854],[-428,-833],[-85,-498],[245,-77],[365,-231],[185,-282],[15,-169],[116,77],[16,-198],[124,-117],[188,-402],[1304,-2187],[323,-126],[778,200],[227,-241],[183,-318],[1,-102],[220,-290],[214,-127],[136,-227],[129,-435],[280,-349],[411,-242],[336,-148],[790,13],[470,-213],[271,-30],[213,-89],[43,-312],[-46,-453],[38,-363],[200,-416],[198,-115],[244,-559],[101,-121],[85,-556],[106,-341],[134,-67],[118,-392],[58,-1181],[240,-350],[18,-1189],[-2135,1700],[-4575,-3109],[150,-1320],[124,-1326],[165,21],[102,157],[423,128],[256,130],[385,458],[51,150],[185,235],[166,52],[39,157],[308,213],[301,127],[285,411],[126,269],[291,140],[-39,42],[406,731],[-21,133],[240,102],[230,298],[246,-39],[239,32],[243,-94],[169,-174],[163,-69],[335,-307],[176,-403],[-7,-342],[113,-15],[70,-272],[329,7],[199,-59],[283,174],[19,310],[419,241],[443,116],[1063,175],[352,-68],[142,-129],[142,-4],[326,-430],[261,-81],[223,-417],[415,3],[546,181],[87,-327],[-57,-248],[83,-118],[-92,-223],[-56,-310],[13,-267],[-68,-202],[76,-126],[414,-416],[-96,-403],[91,-367],[259,215],[204,273],[194,84],[216,175],[121,170],[140,18],[145,254],[158,-35],[196,236],[28,340],[241,130],[121,163],[547,525],[527,-223],[191,303],[191,146],[392,24],[197,-44],[226,-137],[121,10],[318,-323],[66,-253],[347,13],[160,-73],[231,0],[148,81],[216,5],[64,138],[595,255],[274,-73],[358,219],[137,133],[106,-15],[313,449],[10,106],[434,175],[165,-16],[303,107],[384,433],[211,194],[-645,3695],[-70,229],[-311,257],[-320,532],[-155,667],[-127,263],[-114,390],[-540,569],[-104,203],[-460,518],[-43,377],[28,202],[157,543],[283,381],[76,239],[209,308],[-5,343],[-63,610],[-90,540],[-34,499],[-712,-558],[-165,41],[-333,-206],[-408,-481],[-211,-141],[-273,29],[6,158],[-665,783],[-308,4],[-468,341],[232,93],[-337,799],[879,-311],[381,-166],[478,-2],[857,654],[503,237],[309,350],[-3,126],[127,18],[272,365],[279,639],[22,448],[-157,436],[122,412],[-18,491],[-562,864],[4,276],[-538,548],[-24,477],[341,289],[144,266],[5,122],[177,446],[18,327],[-50,260],[126,131],[108,247],[204,252],[98,392],[-78,216],[78,600],[-22,696],[-41,91],[78,224],[-66,614],[-67,163],[62,265],[-32,277],[147,290],[271,669],[38,408],[152,393],[-5,463],[276,462],[185,858],[95,285],[300,71],[162,414],[119,113],[388,224],[42,92],[727,366],[219,206],[254,135],[302,51],[394,356],[202,223],[300,434],[28,179],[155,344],[-54,326],[44,139],[-59,460],[292,265]],[[5987,54185],[-72,-290],[26,-329],[86,-237],[80,-470],[127,-364],[-254,-492],[-158,-476],[-112,-135],[127,-189],[56,-454],[-55,-427],[-194,-344],[-222,-271],[-378,-197],[-47,-306],[97,-162],[-15,-598],[91,-421],[163,-515],[-180,-335],[-98,-389],[-58,-521],[-151,-383],[-266,-38],[-206,89],[-141,-410],[-245,187],[-310,122],[-148,-411],[-284,-108],[64,-142],[151,-37],[-139,-343],[-113,-129],[110,-204],[49,-401],[91,-413],[104,-113],[-132,-334],[-128,-183],[-159,-566],[-210,-332],[2,-411],[-197,-220],[-185,-125],[-459,-532],[-76,-339],[-205,-199],[-41,-204],[-158,-256],[-370,-82],[-497,-325],[-203,-797],[-16,-417],[-110,-572],[-126,-393],[-268,-1180],[26,-151],[139,-190],[80,-272],[188,-293],[98,-306],[178,-303],[224,-473],[246,-178],[17,-574],[-213,-410],[60,-192],[733,-1392],[230,-260],[200,-549],[97,-378],[199,-463],[200,-330],[136,-601],[173,-162],[-15,-105],[128,-489],[119,-215],[153,-428],[114,-176],[179,-653],[82,-150],[321,-863],[271,-629],[481,-1319],[-42,-744],[53,-134],[-94,-781],[-38,-581],[-617,-85],[-63,-524],[-234,-251],[-230,-170],[-36,192],[-655,-864],[-88,-231],[116,-139],[28,-172],[-88,-296],[97,-173],[127,-21],[81,-143],[70,-445],[-31,-557],[-126,-559],[-162,-99],[-67,-140],[-251,-238],[-94,-271],[-366,-495],[-157,-301],[-248,-250],[-98,-299],[-515,-498],[717,547],[1030,54],[1031,-889],[795,392],[291,-34],[331,224],[179,28],[240,308],[139,98],[94,-200],[666,-399],[384,-427],[314,-123],[340,-25],[703,243],[471,207],[168,23],[469,-36],[640,306],[284,40]],[[32221,44354],[-952,802],[-900,874],[-302,439],[-2038,3149],[-647,480],[-252,255],[-255,-31],[-347,222],[-176,-71],[-420,119],[-258,24],[-159,-88],[-154,176],[-47,417],[-283,102],[-187,634],[-52,275],[-347,384],[-129,90],[-255,352],[-173,149],[-168,11],[-202,136],[-176,251],[-154,-12],[-249,-138],[-401,166],[-419,280],[-288,311],[-186,145],[-41,381],[-156,308],[-363,279],[-288,447],[-209,252],[-72,383],[-239,300],[-42,164],[-104,29],[-165,198],[-280,622],[-177,129],[-28,285],[52,118],[-90,298],[-450,55],[-33,-277],[-190,-40],[3,108],[-817,-1778],[-153,-370],[-569,-451],[-117,-30],[-319,-275],[-88,-151],[-201,-46],[-484,0],[-132,-55],[-177,152],[-432,-32],[-119,-340],[-99,-574],[-245,-398],[-184,-191],[-579,-872],[-354,-135],[-348,-188],[-242,-6],[-637,-179],[-157,-97],[-270,-400],[-393,-133],[-443,502],[-298,212],[-418,563],[-273,325],[-827,430],[-333,-52],[-170,-233],[-530,-359],[-232,-347],[-356,133],[-41,493],[-197,259],[-143,289],[-345,155],[-109,-62],[-337,44],[-96,-128],[-497,256],[-25,-42]],[[37325,26477],[104,549],[-13,222],[62,311],[-56,413],[-95,187],[-155,110],[-36,213],[-185,249],[30,117],[-142,580],[-204,396],[-78,292],[-223,244],[-124,337],[79,206],[-82,420],[-95,63],[-242,339],[-7,117],[122,178],[-86,517],[-273,365],[-290,280],[-382,209],[-96,302],[-107,110],[109,337],[-125,371],[-147,87],[-80,158],[-78,384],[-21,316],[-151,-63],[-118,302],[-526,619],[-129,253],[-186,92],[-463,818],[-120,-29],[-241,111],[-380,1043],[-274,464],[-53,-44],[-163,352],[48,302],[-310,601],[-17,344],[-301,95],[979,2949],[217,689]],[[10427,14626],[149,515],[137,636],[355,374],[167,353],[183,251],[277,254],[157,209],[370,356],[179,499],[114,224],[275,226],[236,42],[359,173],[527,-214],[256,-190],[382,90],[534,-130],[123,-93],[814,-10],[303,-69],[204,181],[510,-85],[1138,702],[826,368],[418,72],[277,126],[489,74],[298,170],[264,927],[469,1238],[-10,340],[119,409],[-26,245],[792,2063],[1321,1975],[560,733],[810,411],[353,422],[321,-220],[107,85],[610,154],[455,205],[82,133],[215,-80],[649,91],[14,-346],[257,-372],[19,359],[157,-245],[103,197],[229,-25],[117,-140],[230,273],[408,89],[51,106],[189,-9],[111,-92],[185,5],[108,199],[235,94],[93,-154],[349,-248],[237,-389],[580,-483],[58,-122],[383,-239],[365,-473],[43,-201],[321,-289],[398,-131],[232,-210],[50,-218],[340,-197],[-91,-333],[284,-164],[313,-51],[554,32],[645,338],[219,203],[702,244],[777,396],[221,74],[114,-64],[150,202]],[[41330,12182],[-219,-501],[115,-421],[104,-14],[78,-492],[307,-265],[15,-149],[237,-591],[0,-333],[197,-198],[146,-334],[149,-117],[-69,-384],[37,-273],[-56,-336],[70,-515],[156,-159]],[[47257,59794],[60,-239],[-5,-651],[-195,-247],[76,-162],[326,-26],[295,-166],[256,-2],[311,143],[257,-99],[207,-279],[471,-203],[28,-238],[318,-315],[-37,-381],[57,-329],[-6,-493],[-53,-20],[-97,-391],[-99,-225],[-77,-991],[18,-349],[209,-288],[180,-336],[71,-238],[-217,-264],[-50,-521],[-134,-308],[32,-752],[-59,-236],[108,-345],[0,-284],[-119,-367],[-24,-250],[73,-241],[288,-440],[-11,-113],[186,-308],[384,-450],[183,-75],[109,-225],[139,-134],[421,-130],[469,25],[432,-384],[170,-484],[199,-149],[61,-377],[202,-405],[220,-199],[-38,-218],[147,-95],[134,56],[87,-215],[452,-260],[-6,-211],[376,-449],[49,-496],[210,-68],[168,-468],[277,-133],[76,-359],[-57,-465],[68,-420],[-89,-608],[-177,-340],[-59,-428],[-118,-318],[-331,-585],[-16,-127],[-266,-679],[-110,-484],[-301,-953],[-179,-191],[-133,-252],[-186,-195],[-60,-279],[-199,-290],[51,-166],[-110,-306],[40,-347],[-118,-131],[-8,-590],[-184,-210],[71,-625],[57,-163],[2,-336],[101,-172],[-55,-320],[114,-369],[-163,-688],[63,-128],[-56,-212],[-166,-66],[-85,-227],[9,-253],[-180,-278],[46,-417],[-94,-341],[-19,-434],[63,-814],[71,-185],[-42,-500],[-144,-361],[60,-113],[-93,-100],[-61,-358],[85,-451],[-78,-236],[-164,-1015],[-38,-742],[-241,-580],[-206,-745],[-322,-199],[-540,112],[-368,-104],[-237,-178],[-207,0],[-333,-161],[17,-432],[-122,-235],[-50,-401],[-71,-76],[-142,-411],[-271,-134],[-92,-223],[-224,-241],[-142,162],[-241,-138],[-195,-208],[-66,-163],[-7,-263],[-129,-122],[-1,-358],[-46,-303],[-89,-71],[-12,-235],[-147,-100],[-255,-21],[-129,-475],[-113,-266],[-185,-139],[15,-195],[-90,-93],[-584,331],[-144,-40],[3,-476],[-49,-141],[-75,-785],[94,-521],[-64,-697],[14,-557],[-258,-504],[-171,-229],[-624,-490],[-346,-62],[-278,-136],[-349,-311],[-402,-478],[-189,-16],[-150,-259],[-179,-131],[-366,-38],[-299,12],[-220,71],[-377,-34]],[[50406,74302],[-133,-311],[-321,-441],[-122,-423],[-310,-742],[-44,-234],[-134,-146],[-92,-560],[-244,-283],[-24,-184],[-161,-346],[81,-153],[-158,-319],[-199,-59],[-42,-146],[-139,321],[-404,-325],[-283,-578],[1,-182],[126,-266],[113,-372],[208,-109],[266,-49],[228,122],[35,-92],[-301,-424],[-171,-688],[-185,-392],[-6,-138],[-203,-395],[-263,-341],[-280,-666],[-340,-271],[-299,-486],[-170,-423],[8,-125],[-192,-589],[-16,-342],[301,97],[93,-26],[250,-402],[340,362],[17,211],[296,168],[29,-275],[-116,-194],[-246,-546],[-224,-239],[-141,-601],[43,-254],[-190,-536],[186,58],[160,-89],[-85,-324],[46,-30],[262,-731]],[[42597,7100],[263,-43],[281,-142],[23,-122],[444,-313],[180,-46],[208,-235],[355,26],[266,-298],[755,-339],[635,-493],[79,-178],[127,-62],[290,10],[491,-255],[155,-200],[242,-555],[294,-492],[25,-133],[221,-289],[52,-177],[101,-32],[504,-829],[-46,-236],[259,-381],[136,-303],[92,-52],[37,-336],[-33,-142],[340,104],[295,35],[256,143],[270,24],[198,-107],[109,166],[386,-297],[336,-12],[276,-56],[185,51],[213,-139],[330,-365],[155,261],[284,156],[193,194],[11,169],[108,184],[732,751],[186,460],[110,-26],[262,109],[393,449],[211,139],[229,313],[204,777],[112,124],[244,-388],[547,295],[970,960],[52,455],[997,1365],[925,819],[1052,1444],[1071,1004],[208,246],[3,299],[440,510],[167,30],[292,224],[85,446],[97,172],[386,307],[1977,408],[1648,305],[1100,292],[205,-50],[714,181],[276,378],[224,193],[275,127],[114,258],[-65,425],[370,173],[400,275],[71,226],[260,160],[62,353],[-13,187],[-448,377],[-138,329],[-485,461],[-237,315],[-448,433],[-267,153],[-198,198],[-565,160],[-239,-19],[-261,196],[-208,370],[-427,181],[-219,193],[-190,93],[-339,738],[-120,166],[-332,268],[-271,72],[-57,308],[-153,339],[-86,415],[202,377],[-91,189],[-59,374],[-421,14],[-457,347],[-200,568],[-340,626],[-242,334],[-157,71],[-232,250],[-129,334],[-267,309],[-84,591],[-453,504],[-364,177],[-347,374],[16,344],[-134,290],[-113,34],[-309,448],[-34,263],[-114,132],[-29,187],[117,455],[-140,17],[-178,167],[-24,355],[180,294],[5,209],[221,130],[81,253],[258,378],[488,387],[229,-7],[93,224],[74,-1],[286,225],[256,110],[213,325],[376,390],[51,391],[-6,559],[-76,290],[-2,367],[213,284],[-41,304],[51,258],[-160,226],[-207,66],[-428,-64],[54,1840],[-209,930],[-109,185],[-30,347],[-170,278],[-232,163],[-57,654],[-100,474],[-18,492],[-112,444],[86,613],[140,287],[4,163],[350,998],[21,470],[-167,509],[161,1289],[783,2023],[-62,363],[45,536],[-46,271],[2,479],[-88,317],[22,208],[-85,275],[123,200],[-179,488],[-324,98],[-82,461],[-184,192],[-233,581],[-65,590],[141,635],[-266,848],[-108,807],[257,348],[150,391],[259,400],[324,630],[-107,965],[49,76],[55,700],[147,371],[270,518],[483,699],[168,538],[19,615],[-23,917],[44,328],[-35,532],[58,405],[-51,600],[-168,595],[-53,488],[-118,336],[-13,423],[-102,189],[105,292],[-39,211],[69,351],[-20,184],[64,385],[582,663],[63,188],[191,238],[312,1240],[18,425],[157,1075],[-376,1131],[-172,88],[-351,314],[-206,-23],[53,212],[195,487],[76,71],[124,644],[-54,468],[-101,289],[74,163],[98,829],[118,292],[-224,770],[-104,206],[-352,389],[-762,-581],[-1386,-497],[-567,-390],[-250,-90],[-121,-160],[-251,-103],[-161,17],[-329,-84],[-613,-97],[-404,-271],[-175,220],[-221,174],[-152,39],[-712,-480],[-175,401],[-134,123],[-189,44],[-267,221],[-158,58],[-114,193],[-546,529],[-296,375],[-45,246],[62,176],[-214,216],[-654,338],[-176,222],[-347,82],[-470,291],[-320,128],[-257,324],[-321,183]],[[41330,12182],[-637,436],[-257,282],[-190,301],[-425,431],[-198,340],[-192,674],[-173,197],[12,99],[-442,582],[-5,458],[-206,367],[-203,-92],[-275,-503],[-476,179],[-416,-123],[-309,15],[-195,81],[-54,111],[-356,-42],[-153,-279],[-184,75],[55,442],[64,221],[-44,299],[144,592],[-58,100],[16,259],[80,116],[145,710],[71,38],[293,626],[143,581],[-59,432],[-122,92],[-16,149],[68,375],[-12,246],[64,515],[196,386],[91,51],[76,264],[83,726],[10,312],[149,112],[-7,274],[61,350],[148,283],[26,341],[-77,270],[26,252],[-2,647],[-173,271],[28,178],[-138,196]],[[10427,14626],[-8,-400],[106,-263],[88,-514],[-20,-264],[624,-807],[426,-999],[156,-311],[250,-321],[453,-224],[412,-915],[95,-767],[107,-281],[629,-371],[346,-20],[687,397],[255,23],[71,-68],[421,-110],[216,-413],[422,-354],[234,-114],[174,-181],[340,-76],[413,-172],[744,-789],[323,-370],[350,-351],[325,-381],[346,-467],[859,-1025],[401,-527],[64,-300],[236,-260],[17,-254],[226,-230],[270,-168],[829,-1041],[289,-343],[178,-269],[406,749],[175,208],[657,474],[352,35],[250,203],[629,303],[-89,119],[56,151],[240,42],[4,252],[306,41],[163,225],[173,71],[-61,266],[133,-20],[77,-224],[85,153],[27,304],[125,467],[164,2],[125,228],[122,-65],[135,115],[84,296],[158,295],[638,-436],[263,-89],[114,234],[321,345],[2508,1419],[411,484],[442,291],[734,-822],[677,-211],[649,382],[710,129],[131,147],[720,88],[305,-38],[131,-169],[154,-429],[184,-41],[168,-379],[254,-333],[937,-728],[253,-250],[95,-172],[290,-74],[238,-894],[335,-186],[222,114],[832,85],[236,-215],[271,101],[124,-88],[389,193],[418,137],[79,100],[1087,3389]],[[47257,59794],[-255,49],[-96,125],[-393,-293],[-269,-264],[-508,-370],[-48,-152],[-136,-96],[-57,-322],[-108,2],[-358,-414],[-365,-521],[-220,-187],[-225,-426],[70,-56],[-74,-241],[-253,-246],[-231,-120],[-475,219],[-73,-358],[-344,-256],[-1374,467],[-379,-2412],[-1147,-1616],[-4270,-4144],[-724,-1001],[-771,-2907],[-1953,100]],[[24408,79003],[-135,27],[-457,-251],[-513,-875],[-457,-470],[-330,-94],[-287,-516],[-276,-364],[-380,-206],[-535,-742],[-46,-252],[-210,-505],[-150,-232],[-495,-303],[-272,53],[-199,-238],[-146,-318],[-40,-306],[-140,-359],[-175,-203],[-362,-686],[-303,-718],[-112,-400],[-36,-274],[-137,-234],[-319,-417],[2,-111],[-241,-464],[-237,-634],[-154,-201],[-232,-473],[-99,-325],[-73,-700],[-234,-524],[-264,-451],[-47,-288],[-174,-131],[-106,-264],[5,-241],[-120,-585],[-154,-477],[-91,-585],[-89,-230],[-139,-563],[-238,-585],[-129,-514],[-49,-342],[-235,-284],[-80,-178],[-217,182],[-420,597],[-156,162],[-70,551],[-192,1011],[-2,829],[-45,452],[148,944],[83,318],[-14,329],[177,588],[81,877],[-496,45],[-255,208],[-250,113],[-147,-91],[-253,-46],[-288,108],[-506,665],[-773,593],[-14,-400],[-178,-327],[-513,-406],[-507,-127],[-152,-233],[-276,-638],[-24,-176],[-243,-317],[60,-799],[-388,-842],[-84,-341],[-61,-558],[-207,-359],[0,-147],[-456,-366],[-183,-216],[-345,-212],[-212,4],[-216,-108],[-619,-32],[-270,-299],[-437,-320],[-18,-2186],[-175,-726],[-394,-576],[128,-880],[188,-516],[101,-762],[102,-390],[173,-46],[185,-156],[-37,-597],[-149,38],[33,-957],[52,-247]]],"transform":{"scale":[0.006739486061458211,-0.004800048000480004],"translate":[143.02906667012013,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/sg.json b/src/onegov/election_day/static/mapdata/2025/sg.json new file mode 100644 index 0000000000..67e1945089 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/sg.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"MultiPolygon","id":3201,"properties":{"id":3201,"name":"Häggenschwil"},"arcs":[[[-1,-2,-3,-4,-5,-6,-7]],[[-8]],[[-9,-10]]]},{"type":"Polygon","id":3202,"properties":{"id":3202,"name":"Muolen"},"arcs":[[-11,5]]},{"type":"Polygon","id":3203,"properties":{"id":3203,"name":"St. Gallen"},"arcs":[[-12,-13,-14,-15,-16,-17,-18]]},{"type":"MultiPolygon","id":3204,"properties":{"id":3204,"name":"Wittenbach"},"arcs":[[[-19,13,-20,-21,2,-22,-23,-24,-25]],[[-26,0,-27,8]]]},{"type":"MultiPolygon","id":3211,"properties":{"id":3211,"name":"Berg (SG)"},"arcs":[[[24,-28,-29,-30]],[[-31,22]]]},{"type":"Polygon","id":3212,"properties":{"id":3212,"name":"Eggersriet"},"arcs":[[16,-32,-33,-34]]},{"type":"Polygon","id":3213,"properties":{"id":3213,"name":"Goldach"},"arcs":[[-35,-36,-37,-38,-39,-40]]},{"type":"Polygon","id":3214,"properties":{"id":3214,"name":"Mörschwil"},"arcs":[[29,-41,-42,39,-43,14,18]]},{"type":"Polygon","id":3215,"properties":{"id":3215,"name":"Rorschach"},"arcs":[[-44,-45,36]]},{"type":"Polygon","id":3216,"properties":{"id":3216,"name":"Rorschacherberg"},"arcs":[[37,44,-46,-47,-48,32,-49]]},{"type":"Polygon","id":3217,"properties":{"id":3217,"name":"Steinach"},"arcs":[[28,-50,-51,40]]},{"type":"Polygon","id":3218,"properties":{"id":3218,"name":"Tübach"},"arcs":[[41,50,-52,34]]},{"type":"Polygon","id":3219,"properties":{"id":3219,"name":"Untereggen"},"arcs":[[48,31,15,42,38]]},{"type":"Polygon","id":3231,"properties":{"id":3231,"name":"Au (SG)"},"arcs":[[-53,-54,-55,-56,-57,-58]]},{"type":"Polygon","id":3232,"properties":{"id":3232,"name":"Balgach"},"arcs":[[-59,-60,53,-61,-62,-63,-64]]},{"type":"Polygon","id":3233,"properties":{"id":3233,"name":"Berneck"},"arcs":[[54,59,-65]]},{"type":"Polygon","id":3234,"properties":{"id":3234,"name":"Diepoldsau"},"arcs":[[-66,-67,-68,61]]},{"type":"Polygon","id":3235,"properties":{"id":3235,"name":"Rheineck"},"arcs":[[-69,-70,-71,-72]]},{"type":"Polygon","id":3236,"properties":{"id":3236,"name":"St. Margrethen"},"arcs":[[-73,70,-74,56]]},{"type":"Polygon","id":3237,"properties":{"id":3237,"name":"Thal"},"arcs":[[-75,46,-76,68]]},{"type":"Polygon","id":3238,"properties":{"id":3238,"name":"Widnau"},"arcs":[[-77,65,60,52]]},{"type":"MultiPolygon","id":3251,"properties":{"id":3251,"name":"Altstätten"},"arcs":[[[-78,-79,-80,-81]],[[-82,-83,-84,-85,-86]]]},{"type":"Polygon","id":3252,"properties":{"id":3252,"name":"Eichberg"},"arcs":[[-87,79,-88]]},{"type":"Polygon","id":3253,"properties":{"id":3253,"name":"Marbach (SG)"},"arcs":[[-89,-90,-91,77]]},{"type":"Polygon","id":3254,"properties":{"id":3254,"name":"Oberriet (SG)"},"arcs":[[-92,85,-93,87,78,90,-94,62,67,-95]]},{"type":"Polygon","id":3255,"properties":{"id":3255,"name":"Rebstein"},"arcs":[[63,93,89,-96]]},{"type":"Polygon","id":3256,"properties":{"id":3256,"name":"Rüthi (SG)"},"arcs":[[91,-97,81]]},{"type":"Polygon","id":3271,"properties":{"id":3271,"name":"Buchs (SG)"},"arcs":[[-98,-99,-100,-101,-102]]},{"type":"Polygon","id":3272,"properties":{"id":3272,"name":"Gams"},"arcs":[[-103,-104,-105,99]]},{"type":"Polygon","id":3273,"properties":{"id":3273,"name":"Grabs"},"arcs":[[-106,102,98,-107,-108]]},{"type":"Polygon","id":3274,"properties":{"id":3274,"name":"Sennwald"},"arcs":[[100,104,-109,-110,83,-111]]},{"type":"Polygon","id":3275,"properties":{"id":3275,"name":"Sevelen"},"arcs":[[-112,-113,-114,106,97]]},{"type":"Polygon","id":3276,"properties":{"id":3276,"name":"Wartau"},"arcs":[[-115,-116,112,-117,-118,-119]]},{"type":"Polygon","id":3291,"properties":{"id":3291,"name":"Bad Ragaz"},"arcs":[[-120,-121,-122,-123]]},{"type":"Polygon","id":3292,"properties":{"id":3292,"name":"Flums"},"arcs":[[-124,-125,-126,-127,114]]},{"type":"Polygon","id":3293,"properties":{"id":3293,"name":"Mels"},"arcs":[[118,-128,-129,-130,119,-131,-132,123]]},{"type":"Polygon","id":3294,"properties":{"id":3294,"name":"Pfäfers"},"arcs":[[130,122,-133]]},{"type":"Polygon","id":3295,"properties":{"id":3295,"name":"Quarten"},"arcs":[[125,-134,-135,-136,-137]]},{"type":"Polygon","id":3296,"properties":{"id":3296,"name":"Sargans"},"arcs":[[127,117,-138]]},{"type":"Polygon","id":3297,"properties":{"id":3297,"name":"Vilters-Wangs"},"arcs":[[129,-139,120]]},{"type":"Polygon","id":3298,"properties":{"id":3298,"name":"Walenstadt"},"arcs":[[107,113,115,126,136,-140]]},{"type":"Polygon","id":3311,"properties":{"id":3311,"name":"Amden"},"arcs":[[-141,-142,134,-143,-144,-145]]},{"type":"Polygon","id":3312,"properties":{"id":3312,"name":"Benken (SG)"},"arcs":[[-146,-147,-148,-149]]},{"type":"Polygon","id":3313,"properties":{"id":3313,"name":"Kaltbrunn"},"arcs":[[-150,-151,147,-152,-153]]},{"type":"Polygon","id":3315,"properties":{"id":3315,"name":"Schänis"},"arcs":[[144,-154,-155,148,150,-156]]},{"type":"Polygon","id":3316,"properties":{"id":3316,"name":"Weesen"},"arcs":[[153,143,-157]]},{"type":"Polygon","id":3338,"properties":{"id":3338,"name":"Schmerikon"},"arcs":[[-158,-159,-160,-161]]},{"type":"Polygon","id":3339,"properties":{"id":3339,"name":"Uznach"},"arcs":[[159,-162,-163,151,146,-164]]},{"type":"Polygon","id":3340,"properties":{"id":3340,"name":"Rapperswil-Jona"},"arcs":[[-165,157,-166]]},{"type":"Polygon","id":3341,"properties":{"id":3341,"name":"Gommiswald"},"arcs":[[152,162,-167,-168,-169]]},{"type":"Polygon","id":3342,"properties":{"id":3342,"name":"Eschenbach (SG)"},"arcs":[[-170,-171,166,161,158,164,-172]]},{"type":"Polygon","id":3352,"properties":{"id":3352,"name":"Ebnat-Kappel"},"arcs":[[168,-173,-174,-175,155,149]]},{"type":"Polygon","id":3359,"properties":{"id":3359,"name":"Wildhaus-Alt St. Johann"},"arcs":[[139,135,141,-176,-177,108,103,105]]},{"type":"Polygon","id":3360,"properties":{"id":3360,"name":"Nesslau"},"arcs":[[174,-178,-179,175,140]]},{"type":"Polygon","id":3374,"properties":{"id":3374,"name":"Lichtensteig"},"arcs":[[-180,-181,-182]]},{"type":"Polygon","id":3379,"properties":{"id":3379,"name":"Wattwil"},"arcs":[[180,-183,172,167,170,-184,-185]]},{"type":"Polygon","id":3392,"properties":{"id":3392,"name":"Kirchberg (SG)"},"arcs":[[-186,-187,-188,-189]]},{"type":"Polygon","id":3393,"properties":{"id":3393,"name":"Lütisburg"},"arcs":[[-190,186,-191,-192,-193,-194,-195]]},{"type":"Polygon","id":3394,"properties":{"id":3394,"name":"Mosnang"},"arcs":[[-196,183,169,-197,187,189]]},{"type":"Polygon","id":3395,"properties":{"id":3395,"name":"Bütschwil-Ganterschwil"},"arcs":[[194,-198,181,184,195]]},{"type":"Polygon","id":3396,"properties":{"id":3396,"name":"Neckertal"},"arcs":[[179,197,193,-199,-200,-201,-202,177,173,182]]},{"type":"MultiPolygon","id":3401,"properties":{"id":3401,"name":"Degersheim"},"arcs":[[[192,-203,-204,-205,198]],[[200,-206]]]},{"type":"Polygon","id":3402,"properties":{"id":3402,"name":"Flawil"},"arcs":[[-207,-208,-209,-210,203]]},{"type":"Polygon","id":3405,"properties":{"id":3405,"name":"Jonschwil"},"arcs":[[-211,-212,-213,-214,190,185]]},{"type":"Polygon","id":3407,"properties":{"id":3407,"name":"Oberuzwil"},"arcs":[[202,191,213,-215,-216,206]]},{"type":"Polygon","id":3408,"properties":{"id":3408,"name":"Uzwil"},"arcs":[[-217,-218,-219,214,212]]},{"type":"Polygon","id":3422,"properties":{"id":3422,"name":"Niederbüren"},"arcs":[[-220,-221,-222,-223,-224]]},{"type":"Polygon","id":3423,"properties":{"id":3423,"name":"Niederhelfenschwil"},"arcs":[[-225,221,-226,-227]]},{"type":"Polygon","id":3424,"properties":{"id":3424,"name":"Oberbüren"},"arcs":[[225,220,-228,207,215,218,-229]]},{"type":"Polygon","id":3426,"properties":{"id":3426,"name":"Zuzwil (SG)"},"arcs":[[226,228,217,-230,-231]]},{"type":"Polygon","id":3427,"properties":{"id":3427,"name":"Wil (SG)"},"arcs":[[-232,229,216,211]]},{"type":"Polygon","id":3441,"properties":{"id":3441,"name":"Andwil (SG)"},"arcs":[[-233,-234,-235]]},{"type":"Polygon","id":3442,"properties":{"id":3442,"name":"Gaiserwald"},"arcs":[[-236,19,12,-237,232]]},{"type":"Polygon","id":3443,"properties":{"id":3443,"name":"Gossau (SG)"},"arcs":[[11,-238,208,227,219,-239,233,236]]},{"type":"Polygon","id":3444,"properties":{"id":3444,"name":"Waldkirch"},"arcs":[[223,-240,3,20,235,234,238]]}]}},"arcs":[[[64583,93340],[-6,124],[-413,243],[-316,89],[-685,84],[-184,199],[368,-73],[-200,271],[197,-36],[489,177],[87,155],[725,-422]],[[64437,93031],[146,309]],[[62648,92039],[166,364],[244,103],[-98,103],[276,111],[-227,286],[257,243],[-218,142],[291,16],[421,-100],[247,-148],[278,-267],[152,139]],[[59217,93735],[40,-407],[-163,-224],[186,-217],[511,214],[345,-445],[347,-9],[681,-499],[326,58],[273,129],[54,-420],[352,-435],[283,-68],[99,123],[-154,391],[251,113]],[[58692,96437],[-116,13],[-99,-285],[-111,127],[-173,-118],[-278,93],[-15,-220],[-175,-141],[-49,-205],[147,-100],[-83,-273],[97,-87],[-112,-347],[117,-154],[384,330],[300,170],[228,-40],[324,-483],[-57,-584],[196,-398]],[[61230,96232],[-146,250],[111,459],[-249,30],[-161,-184],[-162,-365],[25,-104],[-211,-371],[28,-172],[-117,-416],[-696,343],[-14,246],[-296,193],[-239,25],[-226,260],[-185,11]],[[64645,94151],[146,265],[357,-3],[109,145],[27,655],[-263,180],[-381,34],[-81,-110],[-721,352],[-32,-56],[-633,125],[-11,-387],[-452,75],[-280,-16],[-338,81],[-551,258],[-230,-85],[-223,-373],[-162,224],[204,700],[100,17]],[[62883,97011],[96,-368],[406,-180],[101,367],[-256,200],[-347,-19]],[[64631,94043],[-100,-198],[266,-286]],[[64797,93559],[190,8],[144,242],[-500,234]],[[61230,96232],[468,-65],[111,283],[213,-35],[253,497],[-314,84],[294,328],[173,45],[36,164],[372,-54],[255,231],[51,478],[-377,-49],[-297,96],[-497,60],[-188,-90],[-70,143],[-296,246],[-31,239],[-252,127],[132,242],[-92,764],[-155,-402],[-147,-13],[-820,115],[-99,-193],[-548,139],[-108,126],[34,222],[-177,-128],[-385,119],[-354,-225],[151,-237],[-286,-35],[-196,-148],[111,-173],[47,-391],[-88,-263],[-316,205],[-53,146],[-298,202],[-491,78],[-149,-356],[-579,48],[-107,-271],[-209,20],[-1267,-366],[298,-324],[-231,-328],[1,-266],[-362,-110],[24,-330],[92,-261],[-273,32],[-21,233],[-285,191],[-433,-280],[-161,157],[-155,-119],[25,-201],[189,-37],[120,-339],[189,41],[48,-162],[836,-73],[12,-110],[609,180],[-1,129],[593,-135],[39,227],[381,232],[273,-62],[175,449],[366,45],[75,193],[-157,76],[157,239],[176,-245],[304,-129],[298,-293],[315,-173],[443,-51],[48,-144]],[[57778,83190],[-326,59],[-790,-574],[162,-880],[63,-697],[-362,49],[-263,-416],[-52,-348],[78,-165],[360,-242],[175,-287],[-286,-307]],[[64087,86878],[51,-105],[-161,-179],[-278,-9],[69,-200],[-136,-375],[274,-307],[140,-295],[-122,-322],[-172,34],[-184,-134],[-74,-251],[-280,-345],[-466,-184],[-117,-159],[-492,-136],[-131,-197],[-150,-33],[-269,129],[-66,-229],[-436,-88],[-222,-181],[-199,-292],[-381,-127],[-235,-224],[-979,-271],[-203,31],[-520,-254],[-220,-173],[-143,132],[-135,-59],[-330,251],[324,312],[202,449],[-268,103]],[[68623,88074],[-70,-167],[-439,55],[-141,-602],[-103,16],[-96,-238],[93,-37],[-106,-577],[-406,153],[-210,254],[258,157],[-106,531],[-154,145],[-869,-340],[55,376],[-98,309],[-340,-74],[-244,-191],[-183,114],[88,-352],[183,-87],[-45,-278],[-400,299],[-428,-216],[-389,-129],[274,-272],[-44,-192],[-616,147]],[[71778,87862],[-190,159],[-276,62],[-62,137],[-374,-116],[-87,-165],[-160,197],[-174,-369],[-119,-94],[-398,375],[-634,-108],[-267,225],[-165,-106],[-249,15]],[[71854,86330],[-157,218],[328,428],[-229,395],[-18,491]],[[72471,85419],[-135,198],[-333,91],[-27,292],[-122,330]],[[56537,79382],[5,-95],[396,-4],[342,-140],[264,-8],[653,221],[695,177],[619,97],[499,386],[524,110],[342,-122],[43,-145],[150,69],[162,-109],[278,154],[215,-80],[797,210],[912,407],[200,-163],[225,-33],[154,208],[432,190],[269,10],[344,341],[290,146],[120,-88],[269,93],[374,-48],[353,-154],[208,13],[423,-97],[290,-172],[168,-365],[227,-147],[264,40],[338,-79],[-16,114],[225,-95],[478,86],[122,138],[471,72],[213,240],[334,136],[288,27],[524,147],[592,251],[160,218],[219,110],[-149,46],[-83,232],[141,105],[158,-95],[267,383],[-310,470],[-18,166],[345,86],[47,303],[143,26],[-58,165],[51,408],[-94,324],[-220,408],[22,143],[220,271],[18,329]],[[68623,88074],[150,382],[-108,57],[15,452],[-119,225],[123,218],[162,486],[-70,231],[114,370],[445,274],[331,330],[53,201],[-175,166],[26,243]],[[63666,88292],[138,-347],[129,-92],[326,167],[15,-97],[-287,-350],[-52,-219],[152,-476]],[[62648,92039],[64,-46],[30,-459],[129,-498],[271,22],[273,468],[177,114],[407,-170],[89,-264],[-219,-202],[79,-237],[388,-185],[-31,-705],[-166,-149],[73,-225],[306,-109],[315,-429],[-232,-245],[-637,30],[-326,-147],[28,-311]],[[65192,93026],[-283,10],[-276,-110],[-196,105]],[[67282,91857],[-78,-243],[167,-172],[-413,107],[90,183],[-369,43],[-233,129],[-128,-68],[26,324],[-554,76],[-824,-284],[-111,153],[264,178],[-147,129],[246,162],[-163,300],[137,152]],[[68210,91968],[-337,-21],[84,-433],[-432,143],[-243,200]],[[69570,91709],[-276,-155],[-473,38],[-186,-65],[-315,221],[-110,220]],[[64583,93340],[214,219]],[[64631,94043],[14,108]],[[70645,94814],[-291,75],[-171,190],[-117,-106],[-316,16],[-80,-311],[-94,34],[-261,-364],[-352,95],[2,-239],[-196,-504],[-149,-78],[48,-142],[-367,-264],[196,-172],[-141,-381],[57,-254],[-203,-441]],[[71117,93024],[-116,415],[-530,389],[12,106],[-449,216],[26,199],[310,120],[177,-145],[199,125],[64,321],[-165,44]],[[69570,91709],[69,388],[143,158],[244,58],[35,175],[286,18],[626,476],[144,42]],[[67282,91857],[46,200],[-334,438],[-453,86],[-315,344],[-296,142],[131,282],[-659,-52],[-210,-271]],[[77748,88219],[168,-162],[-539,-329],[-339,80],[-850,-218],[-374,-46],[-288,34],[-543,-368],[-202,-9],[-86,129],[-260,-167],[-320,-41],[-480,-145],[65,-59],[-573,-371],[-364,-71],[-282,-153],[-627,7]],[[83104,90390],[-795,108],[-194,-180],[-287,-85],[-59,-220],[-1973,-1015],[-226,-404],[20,-232],[-155,-179],[-237,159],[-395,-105],[-110,239],[-497,-132],[-197,-187],[-251,62]],[[72471,85419],[304,37],[442,-174],[278,127],[506,-196],[257,-273],[240,40],[47,242],[381,109],[957,390],[70,146],[330,254],[276,102],[532,-25],[313,126],[234,-73],[371,154],[345,223],[945,171],[350,234],[33,-72],[574,335],[107,180],[423,413],[324,122],[333,-90],[426,333],[178,62],[505,-59],[163,243],[267,154],[312,-61],[55,136],[-418,316],[-111,340],[92,73],[-211,327],[403,605]],[[75609,93086],[-282,-205],[-145,-413],[-166,-149],[-242,-778],[-294,-221],[-132,-210]],[[77704,92658],[-386,253],[-62,223],[-212,272],[-4,387],[67,201],[-1260,-738],[-238,-170]],[[77796,91497],[8,182],[-199,155],[-257,-22],[-42,303],[225,170],[173,373]],[[77281,89763],[-7,254],[285,78],[-85,209],[96,436],[88,69],[-29,336],[142,89],[25,263]],[[73403,90074],[201,-191],[46,114],[308,-31],[588,218],[232,-380],[103,178],[220,32],[101,180],[565,82],[426,-137],[128,-187],[184,-19],[100,-201],[83,154],[275,-129],[318,6]],[[74348,91110],[26,-170],[-367,-370],[-503,-159],[-189,-160],[88,-177]],[[73214,93181],[-73,-206],[-161,80],[-423,-165],[-714,49],[-334,-172],[-221,40],[-171,217]],[[74348,91110],[-513,140],[-140,211],[380,367],[19,293],[127,226],[-258,-39],[-149,142],[-382,66],[105,394],[-193,54],[-130,217]],[[71778,87862],[182,171],[147,292],[143,4],[82,264],[461,161],[90,155],[-124,100],[217,317],[-145,84],[271,170],[-125,122],[89,165],[337,207]],[[80976,92501],[-638,-40],[-402,-163],[-395,-49],[-759,249],[-379,-29],[-398,64],[-301,125]],[[77796,91497],[340,-31],[413,-181],[245,88],[18,-257],[275,-119],[357,56],[451,168],[452,78],[188,134],[198,728],[200,-21],[43,361]],[[83124,92770],[-327,-124],[-194,84],[-903,-181],[-724,-48]],[[83454,90788],[-88,640],[-168,5],[-116,279],[210,52],[-85,404],[95,32],[-52,367],[-126,203]],[[83104,90390],[350,398]],[[77281,89763],[240,-670],[351,-331],[-87,-205],[-275,-58],[238,-280]],[[73868,94272],[37,161],[-187,51],[237,520],[-265,151],[138,246],[-106,168],[109,200],[-319,274],[-4,202],[-157,86],[-333,-134],[-449,-20],[-277,215],[-329,-65],[21,-119],[-328,-84],[-109,-197],[-493,-303],[-212,-343],[-197,-467]],[[73214,93181],[132,260],[398,221],[-54,217],[178,393]],[[75609,93086],[2,441],[135,151],[-313,153],[-41,-125],[-399,161],[-705,82],[68,251],[-488,72]],[[93996,81577],[193,140],[478,47],[349,682],[-134,157],[184,275],[245,519],[269,-100],[418,38],[22,-141],[1212,104]],[[94277,82651],[66,-482],[-690,-449],[343,-143]],[[94275,86659],[250,-838],[194,-54],[-359,-449],[142,-144],[126,61],[204,-362],[-122,-270],[-178,38],[-65,-277],[306,-65],[-165,-341],[-27,-288],[-396,-268],[237,-379],[-179,-35],[34,-337]],[[94686,86800],[-411,-141]],[[97094,87304],[-202,161],[-442,-268],[-640,-158],[-793,-76],[-331,-163]],[[97232,83298],[-83,576],[-174,642],[-487,1108],[-117,472],[100,480],[268,396],[355,332]],[[91958,82838],[-500,-125],[-197,-195],[-226,-91],[-593,-90],[-115,80],[-235,-152],[-304,-41],[-294,-154],[-9,-112]],[[94277,82651],[-302,151],[-321,43],[2,-79],[-381,29],[-268,-81],[-148,84],[-901,40]],[[94434,80877],[81,61],[-455,512],[-64,127]],[[93922,79354],[107,169],[-640,556],[1045,798]],[[92570,77546],[1352,1808]],[[89485,81958],[344,-287],[200,29],[77,-138],[-142,-126],[292,-62],[233,-283],[192,40],[261,-347],[-135,-62],[359,-519],[226,139],[230,-318],[-240,-119],[701,-971],[-575,-383],[1062,-1005]],[[94275,86659],[-341,-117],[-598,-105],[71,-169],[-223,7],[-302,-331],[-593,-196],[-249,-282],[-585,-303],[-294,-71],[-1002,-569],[-144,-35],[34,-223],[153,-213],[-112,-142],[606,-312],[-40,-97],[405,-74],[-146,-153],[636,-135],[407,-301]],[[97352,81504],[-189,-937],[-305,70],[-94,-393],[-266,125],[-124,-389],[-398,-835],[-278,82],[-819,367],[40,255],[411,467],[-239,88],[-191,244],[-182,-73],[-284,302]],[[94429,75568],[213,-157],[240,129],[588,204],[375,63],[1213,11],[725,130],[553,224],[410,257],[385,400],[481,591],[335,629],[45,361],[7,828],[-43,231],[-236,334],[-145,91],[-1061,448],[-320,263],[-526,872],[-316,27]],[[93922,79354],[83,-143],[-194,-1383],[-56,-166],[590,-157],[95,154],[317,-84],[-118,-194],[1065,-278],[-473,-636],[-802,-899]],[[88412,93745],[-100,-384],[247,-169],[-94,-222],[720,-367],[-629,-568],[-309,-693],[115,-145],[-175,-407],[360,19],[-102,-164],[70,-487]],[[90500,90439],[-135,215],[-1155,2297],[-283,400],[-515,394]],[[89957,89630],[388,398],[4,176],[151,235]],[[88515,90158],[450,-42],[94,-113],[898,-373]],[[89957,89630],[26,-271],[417,177],[368,16],[58,-253],[894,-634],[345,-139],[665,-413],[620,-134],[250,22],[117,-128],[944,-384],[154,-319],[-119,-84],[-10,-286]],[[97094,87304],[780,789],[114,205],[34,346],[-162,238],[-424,184],[-1202,217],[-606,40],[-1350,29],[-327,48],[-408,224],[-490,615],[-509,921],[-272,229],[-196,30],[-187,-188],[-60,-526],[-89,-332],[-170,-235],[-203,-104],[-542,106],[-325,299]],[[83454,90788],[562,110],[201,-77],[363,177],[240,-261],[271,39],[67,-312],[-177,-189],[101,-200],[417,216],[293,52],[144,-108],[286,156],[162,3],[477,-210],[-10,-63],[685,110],[277,2],[427,-106],[275,31]],[[88412,93745],[-1186,808],[-492,484],[-279,761],[107,73],[-17,278],[-194,-79],[-194,-229],[-231,78],[-103,-100],[40,-216],[-93,-138],[135,-159],[-97,-269],[-167,-169],[-250,-102],[-299,-442],[29,-165],[-216,207],[-282,-984],[-360,-171],[1,-138],[-757,-249],[-178,245],[40,-255],[-196,-134],[-49,90]],[[97352,81504],[10,624],[-130,1170]],[[90845,75782],[-196,519],[-192,329],[-749,318],[-766,784],[-641,295],[-451,-35],[343,324],[41,175],[-394,29],[-366,223],[-306,378],[-278,69],[-18,197],[114,153],[-106,160],[-292,52],[-207,230]],[[83078,70999],[-198,-196],[324,-122],[115,-126],[-9,-211],[389,-144],[78,-197],[163,-5],[239,-389],[285,69],[162,-284],[271,118],[64,-183],[281,136],[268,416],[754,835],[-76,72],[-263,785],[654,205],[-34,523],[363,12],[784,-100],[87,22],[-163,457],[232,173],[686,280],[712,331],[208,165],[138,248],[88,334],[184,271],[454,473],[345,584],[182,231]],[[80498,73437],[379,-283],[345,211],[161,246],[356,354],[366,196],[181,31],[902,357],[216,-9],[331,-317],[726,-417],[5,-509],[-543,67],[-424,-54],[-396,-458],[228,-137],[393,166],[343,-236],[153,72],[177,-240],[233,-174],[-4,-224],[185,-363],[-73,-27],[217,-419],[-847,-265],[-98,171],[-280,-78],[-264,-201],[-342,209],[-46,-107]],[[86381,79982],[-399,-413],[-271,-114],[-186,39],[-83,152],[-183,-17],[-39,146],[-217,-44],[126,149],[108,382],[-239,51],[-21,173],[-590,-129],[-156,25],[-802,-296],[-980,-170],[-224,-3],[-8,-129],[-269,16],[-841,-226],[-216,-603],[-197,-100],[58,-122],[-175,-131],[116,-113],[-98,-502],[-180,-54],[165,-90],[-73,-385],[-4,-900],[274,-75],[-525,-446],[8,-197],[-193,-154],[243,-178],[-223,-694],[179,-135],[-168,-158],[239,-119],[-114,-125],[191,-836],[84,-20]],[[85560,61973],[-129,130],[-457,-189],[-77,92],[-593,-228],[-43,-100],[-1471,285],[232,447],[-70,496],[147,412],[96,83],[128,401],[-504,260],[-4,149],[-527,237],[-136,309],[-883,442],[-119,498],[-399,225],[-119,236]],[[84104,60587],[35,169],[265,390],[728,492],[428,335]],[[78729,62522],[407,-198],[12,-167],[171,-8],[401,-256],[524,-33],[524,-102],[247,-215],[452,-291],[183,70],[515,-565],[212,-75],[426,-35],[154,-171],[371,87],[776,24]],[[80034,66056],[-177,-163],[-390,-186],[-261,-313],[213,-152],[-111,-467],[-18,-460],[-267,-614],[115,-366],[-297,-699],[-112,-114]],[[80632,66158],[5,195],[-161,42],[-293,-159],[-149,-180]],[[80498,73437],[8,-366],[101,-165],[29,-906],[5,-1176]],[[80641,70824],[474,201],[212,26],[283,-193],[327,51],[61,-201],[424,354],[433,75],[223,-138]],[[87727,80627],[-181,-9],[-160,-264],[-341,38],[-294,-188],[-226,-233],[-144,11]],[[91967,76742],[-86,200],[-1356,640],[40,165],[-160,275],[227,132],[-221,272],[297,200],[-225,261],[103,74],[-333,323],[-90,-62],[-252,338],[-273,-112],[-864,385],[-184,238],[-133,-17],[-204,382],[-335,-19],[-191,210]],[[90845,75782],[502,880],[439,-163],[181,243]],[[80632,66158],[195,254],[352,14],[349,290],[166,59],[316,-106],[409,-285],[313,-10],[194,-129],[532,-146],[173,70],[1811,-90],[200,109],[161,-68],[458,194],[460,54],[273,-167],[477,-32],[509,-210]],[[80641,70824],[28,-528],[-130,-138],[66,-479],[-214,-51],[103,-185],[-127,-97],[62,-182],[-137,-762],[-72,-26],[-25,-458],[-166,-44],[37,-233],[-395,-297],[-97,-250],[54,-338],[328,-437],[78,-263]],[[92570,77546],[-603,-804]],[[87980,65959],[1487,901],[385,280],[633,881],[133,282],[600,2364],[431,1568],[95,238],[573,822],[2112,2273]],[[89485,81958],[-959,-522],[193,-200],[-313,-34],[-137,-166],[-349,-180],[-193,-229]],[[85560,61973],[325,297],[519,961],[110,348],[233,1055],[90,245],[234,293],[909,787]],[[69469,40072],[853,289],[402,-10],[393,247],[520,167],[81,90],[485,61],[354,255],[947,302],[409,-154],[410,-33],[202,186],[130,326],[241,-15],[60,136],[199,20],[183,268],[-9,208],[182,-64],[406,147],[162,-123],[89,99],[322,-120],[157,53],[575,619],[389,161],[302,-76],[-217,-530],[21,-116],[-255,-221],[-124,-245],[300,-625],[192,78],[1065,91],[92,131],[915,-169],[406,99],[53,-69],[1110,316]],[[78250,49409],[51,-363],[-319,-628],[-422,-1357],[-156,-277],[-303,-896],[133,-237],[-123,-368],[-179,19],[72,-200],[-181,-298],[-183,-112],[16,-211],[-325,-356],[-152,61],[-723,-164],[-390,-152],[-681,-440],[-544,-296],[133,-114],[-148,-192],[-363,71],[-1064,-377],[-289,-16],[-348,-188],[-662,-496],[-815,-209],[-71,-69],[-452,-47],[-180,-201],[151,-207],[-275,-637],[11,-380]],[[78536,50335],[-230,-524],[-56,-402]],[[79851,49590],[-525,260],[52,179],[-842,306]],[[81471,41851],[-349,431],[-780,1485],[-246,502],[-252,897],[-436,1760],[23,552],[179,1083],[161,806],[80,223]],[[68065,49246],[132,-166],[583,-98],[717,7],[387,-195],[470,232],[574,-74],[436,66],[196,122],[286,6],[119,-305],[984,-127],[383,83],[152,97],[1013,216],[942,105],[2294,284],[22,-52],[495,-38]],[[69496,54599],[-71,-17],[-334,-463],[-745,-434],[-200,-163],[325,-1415],[240,-861],[-150,-337],[540,177],[-243,-273],[7,-255],[-258,-391],[126,-302],[-269,64],[-212,-520],[-187,-163]],[[78536,50335],[844,1718],[-116,41],[-1144,73],[-269,-19],[11,206],[-1046,-39],[12,176],[-644,-61],[-499,154],[-803,-139],[-129,66],[-124,268],[-169,170],[9,251],[-245,310],[-151,35],[-182,255],[-537,347],[-264,56],[-109,125],[-337,92],[-226,-50],[-147,151],[-581,333],[-192,-133],[-328,209],[-415,165],[-514,126],[-263,-87],[-331,-428],[-151,-107]],[[68065,49246],[-230,105],[-231,-96],[-298,-316],[-283,-541],[-168,-93],[-133,-427],[-314,45],[-342,-31],[-691,9],[-741,-171],[-169,-239],[-478,-66],[-711,-477],[-198,-296],[-334,-32],[-595,-421],[-38,-129],[-282,-219],[-179,-250],[-59,-332],[77,-307],[-495,-162],[-490,-94],[-67,-339],[104,-227],[-143,-406],[-47,-359],[-169,-372],[-46,-266],[-124,-141],[37,-175],[340,-192],[-26,-146],[173,-76],[305,-432],[548,-102],[-148,-190]],[[69023,39072],[328,342],[143,465],[-25,193]],[[61420,41283],[392,-128],[384,111],[1216,-74],[331,-63],[45,-109],[405,-265],[-4,-366],[-140,-257],[180,-166],[70,-288],[538,-183],[568,6],[564,144],[420,-101],[343,194],[345,80],[182,-56],[588,43],[137,-173],[111,-369],[220,-173],[708,-18]],[[69521,55385],[-9,-257],[-185,-150],[169,-379]],[[78729,62522],[-359,-240],[-102,-359],[-366,-384],[-48,-289],[-345,-486],[-328,-310],[-385,-228],[-242,-372],[-530,-376],[-715,-456],[-246,-87],[-115,-248],[-901,-803],[-266,-63],[-204,-338],[-396,-1],[-511,-250],[-403,-330],[-840,58],[-468,-176],[-68,-121],[-432,-242],[-438,-495],[-278,-428],[-222,-113]],[[79851,49590],[964,2005],[46,183],[169,1226],[322,762],[1464,2399],[265,511],[455,1285],[540,1464],[43,232],[-15,930]],[[83193,37049],[-601,2564],[-458,1316],[-121,249],[-542,673]],[[70910,36049],[463,157],[923,246],[454,457],[86,-79],[493,-38],[418,-89],[121,53],[451,-47],[37,121],[372,205],[218,194],[158,276],[191,-118],[596,-49],[279,-95],[334,135],[399,-364],[57,-363],[288,190],[548,-185],[767,-210],[159,-93],[383,143],[1002,-459],[-39,231],[241,-153],[298,104],[-45,74],[285,87],[46,-122],[325,162],[1975,629]],[[69023,39072],[328,-103],[46,-380],[260,-300],[-83,-86],[228,-373],[36,-291],[202,-271],[300,-81],[100,-315],[359,-185],[26,-373],[85,-265]],[[68213,34041],[203,-303],[405,-200],[31,-134],[243,-207],[109,-351],[95,117],[158,-65],[-26,-225],[75,-315],[289,-319],[112,-28],[351,-341],[-60,-58]],[[70910,36049],[-588,-587],[-31,-119],[-523,-457],[-342,-18],[-86,-133],[-550,-50],[-197,91],[-587,470],[-239,88],[-735,-269],[218,-298],[309,-150],[39,-354],[219,-124],[171,90],[225,-188]],[[78543,29521],[495,312],[1563,872],[2281,1753],[339,443],[331,1065],[80,542],[-31,546],[-85,543],[-323,1452]],[[73497,29160],[387,412],[374,90],[45,135],[235,-149],[116,40],[225,-137],[76,90],[275,-41],[109,-170],[229,81],[148,-53],[607,290],[289,-147],[336,202],[407,-23],[255,-389],[753,318],[180,-188]],[[70198,31612],[172,-340],[1019,338],[682,-474],[131,-337],[452,-514],[15,-144],[522,-554],[306,-427]],[[70167,14867],[180,-199],[61,-408]],[[80711,24574],[-1054,-1172],[-671,509],[-105,-113],[-182,146],[-422,-300],[261,-153],[-540,-664],[250,-217],[-23,-142],[280,-37],[-336,-211],[-86,-182],[-403,-329],[-79,-191],[-258,-264],[-149,-429],[-100,-16],[-206,-423],[-732,-1035],[-498,-788],[-309,-119],[-573,135],[-372,-575],[-94,-285],[-107,-1087],[88,-441],[-702,0],[-568,-121],[-960,-153],[-176,6],[-461,-158],[-442,-592],[-815,-306]],[[84672,15370],[457,61],[103,158],[315,18],[398,116],[734,-35],[491,358],[-2858,3138],[-353,436],[-953,1288],[-298,900],[-277,539],[-1720,2227]],[[70408,14260],[631,-480],[591,-202],[229,-204],[712,114],[86,90],[290,-62],[434,147],[213,-40],[197,-266],[181,-51],[198,152],[-180,409],[-143,104],[-15,412],[-130,275],[-304,434],[308,-35],[245,-131],[427,-12],[-203,243],[-438,727],[770,235],[388,150],[85,-168],[241,-76],[371,143],[305,189],[600,-134],[599,96],[293,197],[252,21],[435,597],[268,106],[432,16],[138,288],[335,-65],[55,268],[251,62],[11,121],[287,27],[-8,223],[135,-9],[131,257],[482,-591],[33,169],[214,123],[268,286],[117,344],[353,280],[479,-303],[429,51],[220,-128],[991,0],[113,-274],[-360,-280],[200,-207],[479,-226],[301,-288],[279,13],[605,-331],[58,-436],[-44,-162],[339,-302],[-348,-218],[-373,-63],[-65,-221],[-209,-294]],[[52793,18904],[478,306],[342,355],[506,241],[172,22],[482,-84],[766,33],[558,-97],[170,565],[113,179],[306,197],[892,274],[562,14],[26,155],[224,228],[-5,318],[188,811],[-314,876],[-134,230],[102,428],[233,453],[345,334],[19,284],[131,182],[-147,222],[290,274],[117,216],[214,175],[891,560],[163,257],[505,267],[1095,33],[601,-599],[402,31],[437,341],[467,976],[315,266],[156,223],[513,214],[177,180],[226,31],[303,388],[-55,81],[196,268],[307,-125],[534,69],[36,223],[133,-103],[266,151],[122,160],[312,-28],[320,233],[148,-135],[188,169],[365,-139],[295,191],[159,2],[1192,1332]],[[49447,23813],[224,-77],[407,-420],[330,-211],[34,-208],[188,-171],[512,-236],[221,-29],[42,-332],[256,-210],[199,-385],[69,-6],[194,-379],[-36,-383],[23,-609],[128,-422],[144,-154],[411,-677]],[[58607,35063],[-473,-43],[-713,-456],[51,-310],[104,-17],[-286,-476],[-196,-56],[25,-268],[-253,-74],[-538,-339],[-22,-671],[-921,-761],[-12,-363],[-554,-863],[-43,-398],[-338,-296],[-70,14],[-649,-385],[-177,8],[-340,151],[-252,-152],[-783,-297],[-933,-115],[-224,-241],[-126,64],[-222,-121],[-141,-189],[-361,-251],[-377,-69],[-72,-405],[-134,-218],[-63,-310],[90,-75],[90,-344],[-207,-167],[39,-93],[-271,-221],[-329,-43],[-192,-219],[9,-184],[266,-307],[190,-118],[50,-202],[-4,-561],[104,-369],[-23,-180],[121,-260]],[[68213,34041],[-341,-431],[-56,-523],[-127,85],[-196,-479],[-436,-208],[-278,279],[-166,311],[-504,435],[-701,499],[-77,200],[-170,121],[-336,-7],[-389,108],[-63,-98],[-195,135],[-148,-142],[-459,-137],[-266,24],[-461,392],[-609,318],[111,-171],[-352,44],[-218,193],[-417,20],[-413,-179],[47,-89],[-528,-20],[-157,-117],[-467,31],[-463,-83],[-211,166],[-77,192],[-483,153]],[[78981,26891],[-445,-337],[-281,396],[27,229],[-381,-18],[-54,-336],[-127,-321],[-450,89],[-11,-750],[-338,-129],[-79,53],[-336,-122],[-325,-217],[-564,351],[-1065,-121],[-400,305],[212,174],[-414,90],[-352,613],[-220,7],[3,136],[-516,379],[62,58],[-509,310],[-126,156],[132,84],[-105,124],[-75,491],[-71,65],[294,176],[295,-14],[735,348]],[[79938,25580],[-449,566],[-508,745]],[[70167,14867],[23,343],[160,408],[-8,144],[-189,116],[-458,483],[-65,358],[-159,280],[-291,182],[-349,366],[-268,106],[-150,242],[-256,127],[14,174],[-226,348],[-22,257],[105,180],[-152,162],[-72,373],[-116,125],[-23,292],[67,221],[268,284],[232,545],[464,252],[126,349],[541,135],[210,319],[-19,307],[478,1018],[329,543],[435,105],[291,-86],[232,-289],[250,53],[242,-356],[62,-278],[225,327],[352,266],[-78,91],[205,189],[6,195],[194,272],[-20,231],[357,405],[589,93],[203,92],[279,-144],[249,348],[358,-248],[907,-202],[452,0],[-69,-198],[464,-123],[27,201],[258,-268],[334,-205],[235,-240],[285,294],[82,183],[106,-148],[262,240],[101,-90],[210,193],[240,-108],[1252,879]],[[53608,7742],[162,1],[326,188],[346,64],[464,-47],[613,209],[243,141],[230,440],[570,548],[477,270],[350,332],[355,82],[485,181],[159,-161],[293,11],[453,205],[232,281],[217,152],[369,144],[154,304],[593,-197],[156,84],[396,388],[164,-196],[341,-99],[559,-82],[304,-106],[155,-222],[479,-190],[407,-106],[807,121],[591,-118],[205,205],[383,180],[425,-300],[842,-202],[282,181],[129,190],[418,-8],[134,137],[153,401],[-7,450],[-125,139],[346,731],[499,227],[-12,122],[226,95],[94,-110],[287,-62],[197,287],[403,169],[246,296],[122,699],[103,69]],[[52793,18904],[205,-372],[34,-417],[-268,-92],[-219,-378],[36,-549],[102,-129],[-63,-343],[-258,-478],[41,-228],[291,-295],[57,-525],[-182,-577],[-116,-80],[-129,-823],[406,-1088],[-144,-326],[-820,-249],[-89,-59],[63,-1082],[-77,-398],[165,-152],[251,-461],[-69,-212],[1131,-546],[170,-152],[136,-449],[0,-352],[161,-350]],[[53608,7742],[-260,-441],[150,-182],[-7,-206],[-208,-407],[-58,-410],[642,-450],[381,-728],[504,-367],[188,-62],[390,-321],[837,537],[323,100],[411,-9],[257,-150],[497,-164],[433,299],[296,25],[236,-96],[721,-127],[966,63],[324,-152],[582,-519],[836,-111],[104,123],[1009,158],[476,4],[530,-558],[445,221],[471,-109],[1177,-211],[494,-52],[284,128],[770,-49],[811,71],[649,-141],[525,-270],[297,-199],[732,-146],[520,17],[560,-48],[139,-91],[347,-35],[208,-146],[465,-69],[632,-276],[344,-314],[587,-135],[382,-463],[163,-261],[332,-139],[356,-349],[159,-80],[459,-445],[417,273],[191,349],[173,664],[-215,733],[463,101],[439,6],[548,-68],[219,496],[94,331],[-247,734],[-77,540],[427,244],[141,404],[279,219],[67,150],[783,291],[641,637],[-1101,490],[-112,741],[147,254],[134,577],[320,270],[271,414],[97,438],[-27,348],[819,353],[-104,226],[156,176],[212,4],[-49,225],[144,353],[174,150],[17,277],[146,415],[315,-31],[173,663],[325,126],[924,106],[316,107],[61,131],[-97,611],[43,315],[-104,154],[106,228],[-171,354],[176,447],[291,256],[251,88]],[[45638,37531],[-95,-1206],[151,-944],[-181,-372],[88,-177],[-35,-290],[-188,-277],[-67,-340],[15,-384],[170,-517],[215,-489],[206,16],[-113,-139],[-144,-655],[15,-216],[246,-1030],[-9,-552],[154,-52],[-112,-215],[-65,-351],[-345,-687],[-213,-186],[-16,-295],[-170,-449],[-186,-235],[-169,-65],[-651,-702],[-366,-61],[-287,-415],[-155,-77],[-188,74],[-697,-143],[-115,-135],[-607,-152],[-384,-257],[-66,-119],[-1280,-897],[1232,-773],[963,-577],[124,100],[727,-366],[176,-187],[453,-29],[638,345],[248,-287],[374,-140],[883,497],[402,326],[1113,626],[321,-62],[259,147],[260,25],[286,-129],[169,-193],[374,-104],[451,54]],[[49022,40915],[-433,55],[-683,-17],[-380,-219],[-248,-62],[-553,-282],[-668,-39],[-361,-141],[-177,-236],[304,-667],[-181,-459],[-4,-1317]],[[51089,41453],[-21,-127],[-364,-154],[-258,-221],[-152,36],[-111,-133],[-152,36],[-469,-67],[-71,146],[-335,-152],[-134,98]],[[58607,35063],[-33,485],[177,201],[-56,112],[-247,48],[102,115],[-408,102],[-202,142],[-409,87],[152,1180],[-4790,0],[-214,1288],[-298,573],[-88,570],[-180,-88],[-179,48],[-439,362],[102,681],[-239,290],[-269,194]],[[78981,26891],[-179,407],[-504,1475],[-20,273],[74,263],[191,212]],[[80711,24574],[-773,1006]],[[61420,41283],[-656,114],[-337,96],[30,176],[-335,471],[-130,-26],[-239,381],[-93,34],[-731,-49],[-192,-172],[-380,11],[-118,149],[-384,-98],[-387,143],[-247,-95],[-290,58],[-218,-103],[-412,-26],[-314,-196],[-306,102],[-539,-138],[-213,-130],[-574,-82],[-77,142],[-182,8],[-222,-171],[-665,103],[-140,99],[-381,-111],[-138,-223],[-704,-110],[-111,47],[-464,-254],[-182,20]],[[49752,46558],[-1059,-450],[-345,-183],[-525,-189],[-102,33],[-439,401],[-20,165],[-559,82],[-368,134],[-177,-61],[-360,81],[-263,207],[-349,-136],[-234,142],[-355,-150],[-343,167],[-148,200],[-407,14],[-241,-113],[-483,53],[-253,127],[-256,-80],[-991,-451],[-872,-317],[-70,174],[-846,-206],[-391,6],[-397,-181],[-387,-88],[-307,27],[-495,864]],[[49022,40915],[88,514],[10,433],[381,702],[-102,218],[-315,20],[-163,135],[257,586],[-75,178],[185,239],[170,-18],[449,220],[104,150],[222,89],[38,131],[366,366],[7,102],[328,257],[-326,-86],[-370,149],[-98,153],[3,279],[-269,294],[-160,532]],[[37052,38741],[2357,-72],[1364,-440],[4865,-698]],[[36297,42913],[-104,-341],[-108,-59],[-109,-600],[76,-411],[-126,-1037],[248,-1029],[363,-234],[515,-461]],[[37710,46830],[-252,-188],[-237,-277],[-77,-325],[-174,-193],[-155,-484],[28,-357],[-40,-416],[-132,-65],[-10,-498],[88,-182],[-243,-272],[-59,-518],[-150,-142]],[[20575,50627],[-594,-292],[-386,-1955],[-905,179],[358,-1620],[83,-513],[103,-147],[-35,-285],[91,-480],[916,-70],[102,279],[262,-47],[67,305],[357,-64],[19,116],[344,118],[697,-162],[804,-337],[506,-298],[-138,-205],[658,-331],[61,79],[253,-227],[98,112],[290,-266]],[[21631,50228],[-756,-188],[-300,587]],[[27677,48306],[-181,21],[-288,-103],[-119,308],[132,274],[-272,261],[-240,-205],[-367,493],[-440,-72],[-83,-115],[-409,-75],[88,183],[-291,-11],[-5,149],[-860,275],[-312,275],[-290,-230],[-252,-4],[-510,99],[-1347,399]],[[24586,44516],[378,109],[296,-21],[292,143],[817,486],[310,630],[-293,300],[930,1331],[261,478],[100,334]],[[36668,48832],[62,195],[-189,265],[20,172],[-309,137],[19,357],[-256,301],[-28,244],[-379,141]],[[27677,48306],[152,292],[221,-68],[176,377],[289,279],[166,-130],[237,-431],[342,395],[113,314],[317,177],[210,-57],[938,1091],[149,-73],[12,-171],[302,126],[411,-246],[321,-111],[429,-230],[155,-433],[205,-207],[134,-339],[372,-295],[101,-210],[316,-278],[255,-471],[167,-69],[316,-352],[-98,-131],[62,-192],[190,-195],[352,208],[-3,159],[677,285],[140,-70],[342,150],[114,232],[7,523],[73,272],[329,405]],[[24288,52850],[-123,-717],[-168,-107],[-406,165],[-149,-217],[196,-250],[-556,-575],[-294,273],[-1414,-845],[257,-349]],[[35608,50644],[-272,-295],[-173,128],[-104,316],[-663,-350],[-340,81],[-295,-123],[-230,45],[-396,-134],[-137,228],[-136,-3],[-404,245],[-354,322],[-131,533],[-246,99],[-147,250],[-531,220],[-208,15],[-284,-213],[-486,-85],[-65,-202],[-257,-144],[-298,-366],[-211,104],[-274,-218],[-402,376],[-265,330],[-44,348],[264,118],[179,515],[-18,235],[-135,170],[-305,156],[-226,204],[-169,-105],[-308,46],[-521,-187],[-251,-168],[27,-274],[255,-332],[33,-268],[-352,-9],[-624,213],[-158,190],[-374,83],[-242,-24],[-186,150],[-555,151],[-176,-215],[-125,50]],[[32040,38226],[-270,97],[511,218],[231,178],[-197,255],[-343,146],[-13,126],[494,461],[584,720],[169,-40],[-89,193],[221,246],[358,111],[237,149],[-37,286],[124,292],[200,30],[47,210],[262,-107],[476,396],[230,462],[302,148],[32,-109],[251,134],[-101,76],[245,323],[333,-314]],[[24586,44516],[4994,-4572],[370,-353],[1213,-924],[242,-314],[223,-140],[412,13]],[[37710,46830],[-132,264],[-46,417],[-295,271],[22,195],[-176,310],[-131,12],[-257,360],[-27,173]],[[32040,38226],[2409,306],[828,179],[167,75],[723,-277],[243,18],[642,214]],[[14032,52997],[81,-148],[-206,-121],[336,-1749]],[[18268,53997],[-336,-106],[-93,55],[-1082,-302],[-22,-213],[-726,164],[-539,-304],[-852,-85],[-586,-209]],[[19585,51315],[1,389],[132,11],[53,445],[-154,49],[-1,237],[-210,153],[-395,-114],[114,295],[-182,94],[81,190],[234,218],[-390,138],[-195,-19],[-202,187],[64,289],[-267,120]],[[14243,50979],[2543,394],[1537,-247],[265,7],[997,182]],[[21197,54940],[-458,-150],[-250,-135],[-413,-7],[-416,-160],[-519,-134],[-127,-239],[-746,-118]],[[24288,52850],[-261,328],[-338,84],[-111,145],[65,182],[-145,177],[-193,15],[-186,151],[-291,-87],[-185,67],[-230,-155],[0,189],[-252,-37],[8,99],[-509,-98],[-7,139],[244,53],[-7,192],[-198,112],[200,234],[-17,202],[-456,0],[-222,98]],[[19585,51315],[494,-50],[330,-311],[166,-327]],[[14032,52997],[-152,121],[0,310],[-224,68],[-311,-63],[52,310],[-1096,353],[-197,291],[-468,182],[-576,150],[-275,172],[-213,-54],[-777,166],[-443,-139],[-201,-144],[-148,227],[8,204],[-480,222]],[[8531,55373],[-405,-213],[-38,139],[-475,-145],[-161,-111],[-401,238],[-230,-78],[-96,239],[-222,135],[32,368],[-109,-7],[15,231],[-501,-169],[-335,-171],[3,-251],[-728,-14],[-188,153],[-144,-17],[-40,169],[-194,9],[-176,144],[-342,-29],[-253,236],[-601,-117],[-657,-285],[-318,-32],[-505,-168],[-676,-164],[19,-207],[-249,-141],[-172,-216],[28,-144],[-317,57],[-77,-529],[1529,-2865],[364,-402],[479,-404],[750,-450],[665,-263],[632,-155],[405,-56],[640,-23],[659,59],[8102,1255]],[[28159,59001],[-758,93],[-861,-46],[-314,-172],[-345,-100],[-186,-155],[-775,-139],[-146,12],[-327,205],[-134,-68],[-105,-299],[-466,-374],[-38,-158],[-340,-220],[-370,-164],[-48,-142],[-391,-214],[332,-450],[348,-143],[-289,-297],[-547,-88],[-253,-299],[-582,-210],[-367,-633]],[[31861,56449],[-76,172],[-338,303],[-403,225],[-75,-43],[-461,263],[-117,146],[-260,53],[-716,442],[-295,17],[-112,135],[22,300],[-416,-32],[-106,306],[-273,94],[-76,171]],[[35608,50644],[-13,422],[154,183],[-261,243],[71,250],[305,408],[-165,293],[-159,61],[-228,241],[107,695],[-179,221],[130,180],[-96,103],[-99,390],[-413,111],[-151,254],[-1223,253],[22,372],[-179,301],[122,167],[-505,47],[-372,149],[-563,291],[-52,170]],[[25570,63706],[-425,-21],[-842,221],[-511,454],[-97,-3],[-324,427],[-54,759],[-449,255],[-70,262],[-482,575],[-312,74],[-252,170],[-309,-3]],[[28159,59001],[-177,382],[-105,47],[125,261],[5,334],[273,401],[163,80],[34,250],[313,196],[92,606],[-113,378],[-177,0],[-663,-196],[-303,-2],[12,235],[-782,369],[-353,33],[-191,99],[-7,269],[-631,731],[-104,232]],[[21443,66876],[-303,-438],[-56,-227],[-436,-623],[-308,-615],[-902,-207],[-306,82],[-411,-106],[-482,-227],[-135,-184],[-240,-650],[-139,-166],[16,-177],[-122,-202],[-202,-128],[-12,-349],[-479,-222],[-186,74],[-251,-198],[-340,-120],[-271,-15],[-200,-137],[332,-170],[176,-254],[290,-163],[165,-337],[10,-376],[192,-7],[219,376],[370,-160],[-119,-294],[29,-193],[-83,-430],[-260,-116],[-132,-194],[-312,-201],[209,-262],[205,-62],[-167,-324],[-303,-11],[55,-275],[-340,-196],[-66,-417],[-136,-186],[-200,-64],[-110,-164],[-464,168],[-78,-179],[-398,-100],[-497,-224],[-1047,-328],[-309,-66],[-43,354],[-360,-171],[-503,-61],[-388,-184],[-237,3],[-681,-186],[-1276,-155],[-530,-37],[44,-658],[-342,-112],[-62,-252]],[[40670,61635],[-10,-87],[-385,-182],[-144,225],[-218,81],[-136,-82],[-205,147],[-644,-166],[2,182],[-351,-116],[-212,85],[-104,-154],[109,-432],[-547,-4],[-438,-77],[-85,65],[-344,-42],[-268,-127],[-105,-147],[-313,-123],[-260,31],[-274,-65],[-310,233],[-371,-74],[362,-233],[190,-395],[-336,-113],[-44,-347],[-187,-402],[-733,-515],[226,-278],[-120,-141],[-492,-282],[-218,16],[-314,-200],[-114,83],[-547,-232],[29,-595],[-82,-384],[-334,-228],[-482,-111]],[[45131,60832],[-10,359],[-234,161],[-299,-44],[-30,-144],[-719,-53],[-335,-140],[-577,18],[-57,78],[-506,-64],[-150,-130],[-158,61],[-479,-57],[-192,-87],[-310,553],[-80,-25],[-325,317]],[[37710,46830],[323,50],[679,486],[277,93],[204,393],[347,352],[-130,386],[143,221],[-41,383],[138,326],[361,346],[124,38],[113,335],[311,130],[154,204],[165,567],[-22,411],[-184,307],[-138,-227],[-68,158],[110,276],[-403,55],[4,201],[-159,7],[168,316],[-107,397],[126,-1],[83,455],[-249,155],[-5,210],[740,276],[-109,168],[44,258],[-80,282],[346,273],[95,149],[381,118],[39,301],[347,718],[180,127],[188,-55],[254,87],[-175,160],[-44,330],[262,350],[-28,155],[296,369],[240,-4],[218,233],[36,287],[253,222],[-188,94],[-75,187],[611,198],[88,-25],[862,290],[1,161],[440,186],[-88,417],[-138,113],[101,547]],[[60526,56627],[-280,-372],[-260,-200],[-152,-211],[20,-214],[-352,-216],[-89,-316],[66,-425],[-679,-6],[-388,-210],[43,-182],[-177,-452],[-821,-544],[-334,63],[-147,-49],[-294,154],[-506,-213],[-198,-377],[-997,-165],[-258,-208],[-308,-59],[-382,-152],[-888,-159],[155,-377],[-335,-9],[-157,-98],[-385,-670],[-65,-365],[79,-130],[-323,-252],[-371,-603],[-130,-354],[386,-21],[55,-356],[144,-165],[-230,-182],[-143,-218],[-165,-83],[-437,24],[-156,-221],[-324,275],[-274,-167],[131,-108],[-134,-257],[173,-193],[151,-28],[26,-184],[-355,161],[-171,-183],[127,-131],[-175,-195],[191,-77],[-120,-128],[-111,-338],[-450,77]],[[69521,55385],[-655,-46],[-745,-206],[-115,-90],[-753,-252],[-418,315],[-407,135],[-131,202],[-478,319],[-229,32],[-234,176],[-105,195],[-724,137],[-840,-20],[-249,92],[-635,412],[-55,251],[-287,-66],[-965,71],[-596,-171],[-75,-117],[-299,-127]],[[46941,60815],[-344,128],[-229,240],[-307,-182],[-2,-231],[-318,21],[-457,-47],[-153,88]],[[60526,56627],[-595,117],[-504,640],[-460,162],[-302,302],[118,413],[-161,249],[-455,-19],[-734,-348],[-474,444],[-393,-18],[-194,306],[-161,36],[-310,455],[-541,-113],[-489,104],[453,151],[-420,277],[-224,215],[-123,-203],[-362,23],[-245,-63],[-413,-237],[-42,-208],[-319,-128],[-28,-99],[-305,-154],[-280,224],[-104,-44],[-303,176],[-450,55],[-691,-230],[-301,-9],[-862,206],[-166,133],[-361,44],[-179,136],[-366,103],[-459,302],[-88,-57],[-286,265],[-104,11],[-627,462],[-275,107]],[[36572,67011],[-505,214],[-221,148],[-207,300],[-165,381],[-186,-28],[-309,124],[312,351],[-598,8],[114,166],[-859,338],[-425,209]],[[32427,69195],[55,-358],[-72,-139],[175,-252],[-85,-161],[309,-218],[-321,-226],[344,-184],[134,-245],[187,-49],[232,166],[564,67],[230,-220],[255,-609],[-383,-395],[243,-191],[677,625],[634,75],[250,-30],[158,-214],[396,46],[217,184],[-54,144]],[[33523,69222],[-662,253],[-434,-280]],[[40670,61635],[148,224],[-221,272],[-98,257],[-226,245],[-22,179],[127,225],[-319,347],[-268,666],[225,206],[-303,176],[-85,200],[-371,245],[241,161],[-220,37],[-50,215],[356,159],[-118,194],[-173,-47],[154,274],[-5,186],[-263,75],[-198,-92],[-608,299],[-180,-125],[-455,213],[-417,301],[-122,203],[17,179],[-241,-87],[-33,112],[-374,22],[4,-145]],[[28696,69928],[-285,-149],[-35,-146],[203,73],[-7,-153],[188,89],[283,-71],[-495,-663],[-19,-155],[-246,-53],[-166,-141],[-366,-52],[-155,-180],[-238,-64],[145,-197],[449,-218],[217,37],[-33,-246],[-244,-86],[-246,-294],[-191,-60],[-257,208],[-97,-160],[136,-97],[-313,-120],[110,-402],[205,-1089],[-437,-349],[-218,-648],[-419,-210],[-425,-517],[-170,-109]],[[32427,69195],[-181,-391],[-370,-114],[-395,-29],[-116,-134],[-663,-193],[-177,-151],[-385,29],[-53,-419],[-143,-90],[-328,153],[26,166],[-387,-110],[-136,441],[-184,254],[-151,-93],[-104,174],[339,164],[329,302],[222,36],[-176,180],[157,239],[-104,270],[-751,49]],[[31735,81221],[-135,548],[-142,324],[38,137],[293,-73],[405,173],[101,141],[-173,278],[-428,260],[-431,195],[170,587],[-84,223],[-208,46],[-233,-108],[-246,43],[-339,366],[-173,-166],[-190,44],[-431,767],[-378,513],[-189,167],[-6,184]],[[30369,77989],[-77,293],[422,170],[387,294],[-81,280],[307,161],[279,285],[-343,393],[-147,357],[667,697],[-48,302]],[[19665,77795],[134,-754],[140,-252],[243,-260],[-147,-375],[346,-111],[-94,-133],[713,-397],[203,20],[202,-127],[111,140],[303,-142],[366,-87],[297,38],[137,320],[154,-48],[110,172],[273,49],[19,209],[206,45],[123,566],[193,-131],[231,197],[21,225],[149,-146],[169,114],[-135,73],[220,111],[114,-147],[162,42],[331,-75],[-27,166],[402,13],[110,-207],[-215,-7],[-120,-148],[276,-63],[-99,-336],[44,-124],[232,-30],[98,-246],[694,128],[91,-171],[505,-65],[168,293],[233,119],[-48,267],[626,6],[169,126],[322,95],[254,-283],[205,-33],[181,294],[-74,218],[310,458],[191,71],[18,147],[286,76],[106,171],[116,-81],[356,204]],[[28956,85870],[-290,150],[143,-251],[-640,243],[-16,-197],[-249,-9],[137,-188],[-241,16],[-207,-244],[-484,179],[16,-245],[-178,-54],[233,-204],[-190,-281],[-328,-134],[-41,62],[355,261],[-212,254],[-244,62],[-139,-317],[-586,-71],[-136,277],[-372,391],[-281,-210],[-91,-544],[-181,-44],[-325,-212],[-104,-148],[-259,-128],[-113,288],[-221,-149],[-309,-39],[-107,98],[-137,-123],[-223,113],[-316,26],[-13,-168],[165,-258],[-639,-266],[10,-96],[-777,-34],[293,-71],[94,-165],[-80,-148],[125,-93],[-191,-240],[254,-123],[-52,-104],[265,-75],[-258,-314],[92,-59],[-154,-740],[-184,-673],[-617,14],[-175,156],[-302,-62],[-42,-194],[-251,-28],[-175,-371],[-84,-391],[-223,-214],[207,-277],[212,-476],[-131,-148],[-142,-494],[-171,-351],[-11,-240]],[[30369,77989],[32,-177],[-276,-451],[-345,18],[353,-346]],[[36694,80333],[-157,247],[-384,-18],[-811,-341],[-729,80],[97,272],[307,349],[45,191],[-277,-157],[-145,431],[-167,-11],[-232,142],[-126,-213],[-177,-93],[-142,118],[-202,-138],[-229,168],[-596,-1],[-183,357],[-194,-43],[-185,-264],[261,-292],[-358,-27],[-375,131]],[[39284,79771],[-215,-33],[78,-140],[-275,-30],[-6,-114],[-222,29],[-224,232],[-206,56],[-129,338],[-676,-90],[-440,22],[-275,292]],[[40310,78487],[-261,175],[-205,370],[-348,190],[-91,253],[221,89],[-342,207]],[[37353,76032],[355,29],[27,100],[-226,88],[-33,181],[109,237],[163,80],[-312,206],[-16,434],[-94,228],[192,454],[270,41],[62,155],[143,-55],[161,207],[199,-3],[432,-247],[57,-121],[503,-297],[96,-146],[357,108],[200,186],[312,590]],[[30133,77033],[41,-123],[346,-157],[461,221],[14,-146],[449,24],[94,176],[374,240],[75,172],[-152,297],[81,223],[238,162],[195,-219],[143,107],[-78,332],[162,67],[194,-244],[548,85],[87,-90],[-79,-244],[157,-248],[-131,-293],[249,-21],[267,85],[309,-336],[295,-94],[137,203],[176,-85],[174,-236],[398,-60],[165,-124],[246,116],[172,-17],[193,-195],[-135,-279],[236,-119],[184,-196],[96,104],[280,-189],[443,251],[116,-151]],[[28696,69928],[-58,165],[-335,-32],[-244,316],[73,95],[-248,288],[120,212],[237,104],[222,-59],[-8,299],[138,245],[329,57],[-25,135],[378,18],[115,254],[270,209],[279,-46],[132,165],[-178,164],[109,128],[-378,589],[89,193],[313,167],[-14,192],[142,22],[-127,421],[-141,-34],[-187,238],[-74,236],[41,230],[-136,385],[77,214],[-62,146],[136,216],[-125,253],[-143,-41],[-109,312],[132,174],[192,18],[56,280],[449,177]],[[19665,77795],[-392,-9],[-196,-443],[20,-409],[-153,-134],[-113,165],[-293,-103],[-462,165],[-54,-249],[-346,-601],[-588,-167],[-192,-213],[-231,-57],[-146,-342],[227,-180],[323,2],[139,-273],[205,-172],[154,-726],[265,-423],[53,-222],[330,-620],[171,-128],[147,-316],[-79,-222],[545,56],[327,-25],[239,-245],[247,-101],[113,-314],[220,-373],[-123,-180],[98,-731],[-100,-235],[713,-280],[-61,-578],[-146,-245],[-62,-501],[81,-320],[283,-250],[-5,-220],[142,-210],[381,-311],[97,-179]],[[33523,69222],[44,140],[406,51],[-82,348],[-228,170],[-180,12],[-250,-165],[-180,31],[-135,312],[37,410],[79,78],[-93,466],[175,300],[-16,222],[-158,250],[361,-65],[160,56],[-7,209],[-251,101],[25,236],[989,44],[3,261],[-417,14],[12,118],[359,82],[471,345],[293,75],[171,177],[218,72],[-115,361],[-368,350],[30,444],[251,261],[264,453],[251,-140],[47,-287],[262,-18],[-31,-231],[359,-96],[213,14],[65,344],[190,47],[-22,240],[463,310],[165,408]],[[44880,73894],[-154,220],[-244,117],[185,232],[-287,397],[137,186],[-478,682],[44,441],[-169,98],[42,173],[-221,309],[156,92],[90,302],[-688,38],[-298,190],[-256,57],[-39,-199],[-587,-1],[-420,-112],[-272,301],[-192,29],[-96,206],[28,411],[131,69],[3,383],[-753,61],[-232,-89]],[[45432,72522],[59,135],[-220,699],[-203,218],[-10,181],[-178,139]],[[45799,71664],[-468,131],[-67,314],[-107,-35],[-243,178],[290,114],[-104,153],[332,3]],[[46941,60815],[74,382],[425,470],[312,132],[-26,94],[427,182],[225,426],[358,344],[-92,246],[187,106],[88,278],[-416,495],[-105,252],[-136,46],[-302,516],[140,345],[38,525],[-184,375],[-143,149],[-93,269],[48,129],[-216,847],[-312,116],[219,323],[292,48],[5,185],[243,51],[212,203],[432,64],[77,174],[489,342],[250,42],[314,212],[55,191],[-135,344],[-197,278],[-356,330],[-309,577],[-338,140],[-221,-163],[-608,-141],[-273,-151],[-165,79],[-490,-315],[-115,500],[-141,20],[-228,424],[-216,83],[-235,285]],[[40708,80930],[-251,-257],[-355,-250],[-492,-27],[-397,183],[39,-451],[-105,-239],[137,-118]],[[47959,77301],[-52,29],[70,429],[-211,43],[-598,316],[-180,-14],[-404,262],[-334,-126],[-604,18],[-220,360],[-256,-146],[-22,-169],[-567,81],[-5,111],[-232,17],[17,158],[195,357],[225,147],[-324,32],[-228,106],[-66,271],[-286,-83],[-421,165],[-76,96],[187,83],[145,228],[-107,126],[113,192],[-245,45],[-505,-47],[-208,-78],[-386,149],[11,100],[-262,85],[-125,-124],[-52,305],[-452,-138],[-143,101],[-101,307],[-451,-184],[-91,19]],[[44880,73894],[641,-43],[282,-106],[1257,271],[60,143],[260,179],[93,215],[-106,201],[255,282],[137,1],[160,181],[76,330],[205,-19],[41,261],[-134,339],[224,175],[-24,173],[-184,242],[-149,345],[-15,237]],[[45799,71664],[369,427],[265,623],[332,173],[-307,287],[-51,-198],[-224,-41],[-322,-284],[-429,-129]],[[43730,83848],[63,-535],[-422,-104],[-45,-450],[-255,96],[-256,-112],[-340,-365],[-276,71],[-311,-217],[-38,-413],[-181,-267],[-321,-252],[-640,-370]],[[47458,81491],[-252,76],[-134,-109],[58,-177],[-151,-1],[-125,238],[-157,73],[-67,-235],[-459,285],[-87,216],[-362,-104],[-198,128],[-143,462],[-229,167],[185,103],[-292,133],[20,293],[-136,133],[-184,-108],[-142,129],[130,230],[185,83],[-224,128],[-349,-72],[-165,220],[-293,132],[-157,-66]],[[49488,79392],[-326,298],[-363,-41],[-156,-98],[-122,236],[-146,-145],[-66,197],[-273,59],[-286,480],[54,483],[-174,476],[-172,154]],[[47959,77301],[496,490],[117,-125],[269,129],[288,-96],[386,230],[69,297],[-56,359],[-110,216],[46,281],[-205,162],[229,148]],[[29886,86351],[-215,-159],[-182,126],[-231,-72],[204,-219],[23,-150],[-529,-7]],[[30278,86824],[-294,-472],[-98,-1]],[[34766,84883],[52,137],[-435,157],[66,61],[-835,69],[-119,230],[-424,119],[-3,224],[-227,45],[-276,215],[52,161],[-297,62],[-422,273],[-90,236],[-266,-138],[-199,-333],[-179,157],[-269,-180],[-133,148],[-173,398],[-207,-172],[-104,72]],[[36694,80333],[92,32],[-180,486],[227,431],[-216,-26],[-185,-208],[-374,181],[310,72],[63,128],[-162,115],[-323,77],[-90,243],[-226,86],[186,251],[117,386],[-213,358],[-327,118],[269,396],[-356,117],[-19,95],[-338,12],[-363,-69],[-11,234],[-442,-231],[-86,84],[261,254],[-80,133],[205,155],[205,298],[128,342]],[[40333,85439],[-696,-223],[-172,-639],[125,-80],[-45,-396],[530,-48],[597,-129],[-102,-699],[-496,-59],[-147,68],[37,147],[-206,-68],[-896,230],[163,296],[-590,143],[-7,192],[-263,-33],[-330,167],[-275,339],[-158,316],[-246,139],[-51,-206],[-555,-155],[-68,206],[-511,98],[-625,-143],[-580,-19]],[[43730,83848],[-349,199],[-126,-35],[-325,215],[-33,233],[-232,-168],[-281,294],[-238,-156],[-239,-33],[-140,117],[249,187],[-147,126],[-135,-206],[-151,151],[-301,-265],[-147,199],[277,309],[-106,74],[-273,-139],[-85,139],[163,157],[-74,81],[-357,-68],[128,293],[-243,-54],[-105,-160],[-127,101]],[[31891,88126],[-556,-191],[-413,-273],[-230,-217],[-414,-621]],[[36300,89179],[-155,56],[-299,-60],[-247,-257],[-493,-201],[-2104,-375],[-1111,-216]],[[40333,85439],[-59,292],[154,429],[-296,409],[-189,1063],[26,268],[-406,-55],[-1341,-40],[-210,35],[-978,280],[-252,245],[-194,663],[-288,151]],[[48358,86752],[243,-272],[211,50],[58,-114],[293,8],[255,-173],[35,-144],[648,-149],[129,133],[217,755],[-91,84],[76,398],[316,413]],[[43173,89544],[-134,-381],[494,-586],[70,-168],[-51,-280],[179,-228],[220,-65],[192,-423],[270,-126],[136,-264],[143,-35],[-4,-453],[330,-93],[225,145],[583,-103],[237,-332],[202,-13],[179,168],[519,197],[144,-134],[455,42],[215,172],[6,628],[536,-259],[39,-201]],[[46477,91843],[-260,-417],[-525,-196],[-672,-471],[-280,-311],[-565,-376],[-695,-271],[-307,-257]],[[49685,92023],[-559,9],[5,332],[-394,147],[-108,-127],[-372,164],[-565,-204],[-164,75],[-389,-325],[-172,-211],[-2,-222],[-488,182]],[[50748,87741],[-421,90],[-81,90],[75,213],[-286,362],[287,580],[-103,157],[257,398],[-225,179],[-26,425],[-360,110],[19,358],[-271,248],[-28,199],[311,84],[30,296],[-283,253],[42,240]],[[46477,91843],[94,281],[-333,89],[94,75],[-159,561],[375,390],[-257,-112],[-514,81],[-177,-68],[-174,111],[-145,-91],[-237,230],[-414,-249],[-92,92],[118,256],[-531,277],[-56,-83],[-613,-199],[-139,361],[-96,552],[-393,-59],[124,-144],[-129,-190],[-294,66],[-128,-125],[-79,247],[-453,320],[299,770],[-316,97],[-86,-386],[-188,27],[77,286],[-184,78],[-182,-312],[-391,-323],[-16,-198],[257,-271],[-356,-668],[-162,-523],[-509,-339],[-69,97],[-440,-90],[-666,-294],[-114,-130],[-203,1],[-72,121],[-275,80],[-890,-213]],[[36321,89303],[242,-177],[151,154],[273,-99],[1,-139],[-187,-64],[169,-158],[547,-114],[489,-6],[667,116],[13,-134],[795,-285],[217,-168],[286,97],[221,198],[-185,226],[-215,477],[122,322],[-85,145],[175,284],[296,70],[96,-89],[360,149],[389,-314],[363,-38],[-46,-254],[203,-413],[250,-93],[404,371],[4,-168],[200,13],[508,447],[129,-115]],[[37383,92322],[131,-151],[260,-57],[291,-885],[-314,-164],[143,-340],[-295,-340],[-180,-1],[-570,-317],[5,-171],[-209,-2],[-190,-450],[-299,-92],[165,-49]],[[47458,81491],[72,111],[506,423],[-309,261],[-215,-16],[48,209],[-46,687],[153,-67],[128,572],[-372,253],[76,265],[-91,308],[-353,156],[287,460],[-233,24],[167,513],[679,11],[159,198],[-97,216],[-172,83],[1,176],[298,296],[214,122]],[[36321,89303],[-21,-124]],[[33004,91981],[331,-116],[247,-13],[112,-213],[-191,-519],[-369,-269],[-316,8],[-356,-186],[-287,19],[-288,-86],[-151,-161],[-271,-34],[55,-110],[-358,-35],[-823,-239],[-352,-315],[307,-57],[624,-427],[367,-521],[333,-162],[273,-419]],[[37383,92322],[-457,-64],[-152,-79],[72,-292],[-217,-163],[-517,-158],[-231,57],[-204,428],[-225,31],[41,190],[-170,-69],[-1365,161],[-101,57],[-86,-262],[-705,-88],[-62,-90]],[[33004,91981],[-115,-13],[-180,271],[-19,203],[-232,363],[-320,106],[166,186],[-152,124],[92,154],[-129,256],[-134,16],[-6,206],[-227,-27],[-663,-437],[-192,196],[-444,-312],[-318,-13],[-185,-119],[-239,229],[-60,-196],[-225,20],[-153,-166],[61,-302],[-356,-122],[-212,345],[-285,23],[-42,247],[-421,39],[-212,225],[-171,-83],[-253,451],[-207,-8],[92,-156],[-372,-230],[-189,-282],[-107,113],[-558,-281],[-207,-269],[-238,209],[-273,-183],[-294,-5],[-108,-97],[-332,271],[-340,-81],[-226,51],[-251,-344],[160,-132],[-87,-214],[-297,-282],[-158,81],[-8,-233],[-345,-231],[309,-47],[116,-207],[175,46],[6,-604],[371,-61],[-317,-286],[-101,-175],[228,-115],[840,-280],[503,-92],[492,-150],[385,-188],[-122,-208],[73,-368],[207,-163],[-362,-142],[-125,-117],[150,-394],[1616,-502],[678,-65],[9,-79],[339,-37],[428,-321],[37,-312],[388,-74],[96,-105],[434,-151]],[[56698,84574],[28,25]],[[52812,87425],[-332,-257],[200,-423],[-87,-233],[-176,-187],[76,-234],[418,-418],[-376,-344],[264,-75],[90,-124],[329,-39],[290,-335],[373,-189],[113,-355],[556,110],[144,-49],[566,92],[169,-53],[-104,-210],[362,-171],[177,419],[228,110],[119,-286],[442,308],[45,92]],[[56726,84599],[250,424],[459,213],[96,312],[-430,203],[118,189],[-24,244],[-635,506],[-413,48],[-51,259],[-349,70],[44,505],[-211,277],[-332,116],[105,183],[-315,108],[-643,-56],[65,-204],[-173,-154],[-223,-451],[-131,22],[-192,-304],[-369,264],[-227,-137],[-333,189]],[[63666,88292],[-783,43],[-353,-211],[-53,-174],[-194,-161],[-426,-180],[-187,55],[-263,274],[-447,99],[-119,-116],[-196,136],[15,-207],[-345,-21],[-34,-259],[-133,-80],[-331,133],[-189,-93],[21,-139],[-305,8],[159,-371],[-81,-98],[-553,-77],[112,-142],[-7,-382],[-337,109],[-396,-163],[203,-177],[-40,-97],[275,-250],[-83,-188],[-405,126],[-123,-391],[7,-307],[-238,39],[-70,-343],[225,-206],[-594,25],[-279,-86],[2,135],[-395,44]],[[56698,84574],[-6,-361],[-115,-281],[103,-170],[495,-124],[351,154],[310,-185],[84,-273],[-142,-144]],[[49488,79392],[81,-314],[172,182],[164,-143],[168,43],[805,459],[229,-114],[579,343],[351,-46],[123,79],[180,-321],[153,27],[348,236],[433,127],[143,-200],[270,-74],[281,268],[329,-64],[243,-130],[242,-2],[59,-210],[441,78],[276,-108],[178,23],[801,-149]],[[52812,87425],[-425,109],[-208,123],[-15,378],[-293,48],[-441,-137],[-174,63],[-338,-92],[-170,-176]],[[59217,93735],[-230,-54],[-417,-648],[-688,-332],[-57,-342],[-365,-238],[-148,-203],[-588,-308],[-235,205],[-883,117],[-132,64],[-100,347],[-382,13],[-280,100],[-241,-250],[-70,-316],[-653,-143],[-27,-145],[-192,10],[-401,-157],[-344,-295],[-274,-55],[-878,65],[-195,80],[-122,-172],[-474,194],[-222,379],[-75,293],[-148,-53],[-340,51],[-280,210],[-91,-129]]],"transform":{"scale":[0.004340751314554494,-0.004800048000480005],"translate":[262.96460464793256,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/sh.json b/src/onegov/election_day/static/mapdata/2025/sh.json new file mode 100644 index 0000000000..92b65906eb --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/sh.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":2901,"properties":{"id":2901,"name":"Gächlingen"},"arcs":[[-1,-2,-3,-4]]},{"type":"Polygon","id":2903,"properties":{"id":2903,"name":"Löhningen"},"arcs":[[-5,-6,-7]]},{"type":"Polygon","id":2904,"properties":{"id":2904,"name":"Neunkirch"},"arcs":[[6,-8,-9,-10,-11,-12,2,-13]]},{"type":"Polygon","id":2914,"properties":{"id":2914,"name":"Büttenhardt"},"arcs":[[-14,-15,-16,-17,-18,-19]]},{"type":"Polygon","id":2915,"properties":{"id":2915,"name":"Dörflingen"},"arcs":[[-20,-21,-22]]},{"type":"Polygon","id":2917,"properties":{"id":2917,"name":"Lohn (SH)"},"arcs":[[14,-23,-24]]},{"type":"Polygon","id":2919,"properties":{"id":2919,"name":"Stetten (SH)"},"arcs":[[15,23,-25,-26]]},{"type":"Polygon","id":2920,"properties":{"id":2920,"name":"Thayngen"},"arcs":[[21,-27,24,22,13,-28]]},{"type":"Polygon","id":2931,"properties":{"id":2931,"name":"Bargen (SH)"},"arcs":[[-29,-30]]},{"type":"Polygon","id":2932,"properties":{"id":2932,"name":"Beringen"},"arcs":[[-31,-32,-33,7,5,-34]]},{"type":"MultiPolygon","id":2933,"properties":{"id":2933,"name":"Buchberg"},"arcs":[[[-35,-36]],[[-37,-38]],[[-39,-40]]]},{"type":"Polygon","id":2936,"properties":{"id":2936,"name":"Merishausen"},"arcs":[[-41,17,-42,-43,-44,28]]},{"type":"Polygon","id":2937,"properties":{"id":2937,"name":"Neuhausen am Rheinfall"},"arcs":[[-45,31,-46]]},{"type":"Polygon","id":2938,"properties":{"id":2938,"name":"Rüdlingen"},"arcs":[[-47,34,-48,37,-49,38]]},{"type":"Polygon","id":2939,"properties":{"id":2939,"name":"Schaffhausen"},"arcs":[[45,30,-50,-51,-52,41,16,25,26,20,-53]]},{"type":"Polygon","id":2951,"properties":{"id":2951,"name":"Beggingen"},"arcs":[[42,51,-54,-55]]},{"type":"Polygon","id":2952,"properties":{"id":2952,"name":"Schleitheim"},"arcs":[[-56,53,50,-57,0,-58]]},{"type":"Polygon","id":2953,"properties":{"id":2953,"name":"Siblingen"},"arcs":[[33,4,12,1,56,49]]},{"type":"Polygon","id":2961,"properties":{"id":2961,"name":"Buch (SH)"},"arcs":[[-59,-60]]},{"type":"Polygon","id":2962,"properties":{"id":2962,"name":"Hemishofen"},"arcs":[[-61,-62,-63,-64]]},{"type":"Polygon","id":2963,"properties":{"id":2963,"name":"Ramsen"},"arcs":[[59,-65,61,-66]]},{"type":"Polygon","id":2964,"properties":{"id":2964,"name":"Stein am Rhein"},"arcs":[[63,-67]]},{"type":"Polygon","id":2971,"properties":{"id":2971,"name":"Hallau"},"arcs":[[-68,10,-69,-70]]},{"type":"Polygon","id":2972,"properties":{"id":2972,"name":"Oberhallau"},"arcs":[[57,3,11,67,-71]]},{"type":"Polygon","id":2973,"properties":{"id":2973,"name":"Trasadingen"},"arcs":[[-72,-73]]},{"type":"Polygon","id":2974,"properties":{"id":2974,"name":"Wilchingen"},"arcs":[[72,-74,68,9,-75]]}]}},"arcs":[[[25079,70984],[-815,247],[-288,54],[-22,965],[-821,315],[-424,430],[-554,337],[-400,-185],[-192,88],[-256,-58],[-213,79],[-63,-257],[-517,-908],[-107,-321],[-239,-333],[-142,-90],[-153,-221],[-44,-200],[-254,-367],[-131,-25],[-201,-287],[-307,-335],[224,-371],[30,-215],[-119,-193],[-35,96],[-554,-462],[-282,-112],[-406,-487],[-350,-330],[-396,248],[-190,-67],[-449,-340],[-526,-257]],[[23337,59414],[-16,123],[-346,669],[-134,64],[-241,405],[91,149],[-359,362],[76,140],[-429,435],[-71,-101],[-86,373],[-102,212],[-295,428],[-188,178],[411,487],[-486,562],[-430,674],[-421,579],[274,311],[-1010,1203],[509,740],[-507,665],[147,-74],[125,261],[143,-210],[50,213],[420,311],[416,120],[361,511],[149,75],[280,-90],[254,204],[175,542],[241,139],[233,10],[329,-125],[322,-492],[667,-227],[320,368],[595,339],[260,394],[15,643]],[[17922,56356],[294,-425],[825,802],[221,-220],[238,336],[328,-279],[51,59],[311,-318],[318,265],[164,249],[44,-64],[425,220],[-108,595],[2487,776],[-205,1026],[22,36]],[[15883,67422],[125,-574],[159,-498],[225,-1127],[149,-430],[219,-23],[701,217],[-13,-805],[-453,-488],[463,-371],[-168,-366],[-174,-684],[301,-199],[-252,-502],[-121,-395],[415,-723],[-109,-645],[-364,-338],[-264,-155],[-104,-298],[226,-41],[-120,-617],[-128,-415],[-40,-335],[247,-110],[616,131],[316,-417],[395,-368],[-136,-410],[-72,-80]],[[29381,65754],[-52,5],[-398,-1192],[-131,-559],[-156,-378],[-72,-2],[-145,-298],[-77,-505],[-293,-204],[-425,-523],[-100,-480],[-29,-512],[170,-125],[211,-362],[-136,-504],[89,-27],[-176,-502],[-207,-472],[-571,308],[-56,-391],[-495,283],[-518,-59]],[[29675,53914],[1799,801],[61,-341],[557,130],[36,-181],[504,115],[-15,102],[513,118],[-89,602],[525,79],[-38,1119],[18,430],[106,20],[-65,235],[53,343],[-313,131],[214,862],[334,-94],[53,186],[262,143],[-150,477],[-47,536],[-226,913],[-180,912],[-210,286],[-488,541],[-188,458],[120,680],[-332,-85],[27,304],[-769,410],[-300,285],[-268,59],[-351,-9],[-828,283],[-109,160],[530,-105],[204,15],[221,126],[-227,440],[-85,469],[-706,-159],[-447,44]],[[25814,59255],[197,-998],[-458,-155],[408,-2089],[110,-314],[-302,-175],[221,-1090],[336,-704],[446,299],[415,6],[670,142],[310,218],[309,335],[371,-449],[-464,-567],[17,-321],[824,374],[35,-48],[416,195]],[[30224,44901],[451,135],[146,122],[104,493],[57,486],[-237,219],[-219,320],[-202,127],[-502,560],[50,495],[126,222],[141,418],[305,587],[21,424],[-242,358],[-90,433],[-380,-49],[-416,173],[161,445],[-336,111],[130,693],[132,-98],[38,307],[142,4],[25,463],[-503,112],[-32,585],[703,149],[-122,719]],[[26044,42079],[196,79],[464,311],[281,265],[223,294],[204,116],[136,-532],[20,-231],[-87,-458],[162,-245],[457,-352],[770,-366],[165,-245],[139,-11],[-40,479],[-130,283],[-202,1004],[-182,323],[-64,530],[183,222],[42,386],[492,100],[951,870]],[[12423,50542],[445,-112],[109,-252],[290,-418],[340,244],[182,-337],[256,212],[201,-320],[717,-230],[276,-155],[53,-638],[551,-7],[157,-152],[5,-138],[-198,-544],[-13,-180],[105,-146],[394,68],[731,237],[270,116],[233,-58],[107,-175],[89,-373],[217,-377],[162,-103],[507,8],[199,-88],[-196,-462],[-378,-377],[265,-221],[437,-748],[304,-292],[993,-89],[582,66],[807,141],[581,195],[218,402],[183,202],[357,-296],[18,-115],[202,-44],[549,407],[305,127],[168,-615],[772,-305],[187,-27],[394,-203],[-414,-382],[-24,-478],[110,-306],[210,-859],[-8,-203],[146,-181],[173,-8],[295,126]],[[15923,55151],[-505,-293],[226,-648],[160,-27],[49,-153],[-922,-717],[-521,-497],[-584,-790],[-399,-258],[58,-159],[-439,-341],[32,-116],[-690,-460],[35,-150]],[[17922,56356],[-170,-343],[-778,-300],[-1051,-562]],[[25814,59255],[-1386,80],[-420,-18],[-671,97]],[[53087,83484],[-327,300],[-190,-522],[-336,-69],[-305,132],[-157,-366],[-503,612],[-248,-245],[-277,-80],[-150,81]],[[52471,76357],[-63,186],[-231,256],[426,454],[-106,247],[-58,321],[262,388],[287,902],[-32,144],[196,152],[190,-206],[159,240],[84,291],[-16,413],[-129,104],[39,432],[-335,230],[-329,393],[-207,50],[-274,152],[37,308],[293,125],[241,-32],[251,140],[403,701],[-198,352],[-274,384]],[[49181,72876],[223,376],[515,528],[218,426],[44,223],[353,616],[199,130],[457,525],[405,-41],[204,-141],[392,310],[250,367],[30,162]],[[47420,74489],[478,-28],[256,-368],[347,-600],[352,-392],[328,-225]],[[48206,81395],[247,-428],[230,-325],[254,-268],[290,-409],[-247,-459],[-154,-196],[-131,-406],[-453,-639],[-346,-682],[-151,-502],[2,-403],[-103,-434],[-80,-583],[44,-653],[-188,-519]],[[50594,83327],[-160,-261],[-443,343],[-177,-224],[-206,-121],[-632,-713],[-272,-414],[-498,-542]],[[62045,63906],[68,143],[426,-13],[150,95],[362,-214],[357,-460],[201,-621],[189,-289],[40,-331],[-125,-65],[42,-162],[171,-15],[177,-699],[258,-1422],[623,-927],[31,-237],[-24,-523],[-4,-894],[-64,-459],[1139,-520],[187,1],[6,-833],[-133,-129],[75,-351],[125,-341],[492,356],[527,264],[413,135],[706,97],[-248,808],[-93,689],[238,1498],[148,787],[524,2010],[-60,275],[134,359],[79,343],[7,442],[57,222],[374,829],[185,580],[286,392],[-161,317],[-344,368],[-200,150],[-451,173],[-560,64],[-535,328],[-225,41],[22,442],[-366,-54],[-329,217],[-334,-86],[-429,26]],[[63631,66734],[-447,3],[-437,67],[-360,109],[-475,23],[-372,-108],[-250,-583],[-243,-424],[-218,-594],[440,-163],[-72,-569],[275,159],[-37,-627],[610,-121]],[[66179,66712],[-694,104],[-639,-49],[-190,64],[-39,-225],[-325,-17],[-661,145]],[[58606,74725],[146,348],[-6,478],[-56,518],[54,139],[214,225],[86,581],[67,132],[396,381],[114,205],[-68,73],[139,165],[143,317],[68,342],[-13,309],[108,304],[-97,-1],[-179,221],[-215,500],[-130,398],[-233,68],[-188,293],[-249,669],[-226,396],[-319,416],[-89,-71],[-497,398],[-309,473],[-341,394],[-148,590],[-262,349],[-637,505],[-380,117],[-329,192],[-365,96],[-171,-57],[-198,-302],[16,-585],[-243,-131],[-198,9],[-128,95],[-439,-23],[-48,-72],[63,-281],[-134,-284],[-238,-130]],[[52471,76357],[243,184],[195,524],[393,19],[360,-385],[-301,-392],[251,-649],[103,-147],[298,-155],[50,79],[337,1],[148,-348],[290,129],[47,314],[71,54],[106,774],[357,-22],[448,-217],[209,79],[285,477],[265,229],[-15,-199],[198,-67],[174,-330],[426,210],[250,196],[242,-281],[58,-237],[-63,-168],[227,-367],[205,-745],[278,-192]],[[58050,72867],[241,250],[365,44],[-362,592],[-227,155],[353,280],[346,400],[-160,137]],[[49181,72876],[245,-156],[397,-476],[-241,-482],[17,-253],[333,-336],[-260,-332],[-181,-384],[26,-640],[74,-412],[310,-631],[228,-180],[301,-140],[-152,-370],[176,-108],[344,-33],[329,301],[523,602],[-7,55],[603,418],[-14,510],[236,207],[273,343],[464,-420],[-83,-296],[89,-118],[273,61],[198,148],[227,-20],[77,177],[244,114],[-71,203],[211,654],[125,-144],[253,307],[299,89],[282,210],[209,381],[193,252],[269,206],[370,158],[178,268],[319,-81],[169,-258],[329,732],[294,-302],[391,167]],[[58050,72867],[95,-429],[441,-377],[137,19],[-61,-731],[237,-97],[451,-327],[-6,-100],[351,-52],[403,36],[358,-584],[88,2],[47,-347],[336,-16],[252,-231],[-120,-85],[-43,-363],[144,-111],[-419,-880],[-30,-282],[269,-53],[521,-13],[259,-72],[272,26],[549,143],[122,75],[183,-607],[-114,-9],[-14,-289],[330,-151],[106,-123],[437,-105]],[[66179,66712],[-292,648],[-394,1157],[-219,562],[-180,266],[-254,235],[-139,427],[127,173],[149,638],[99,878],[236,736],[79,484],[-4,403],[523,395],[655,571],[103,592],[175,569],[415,669],[630,-226],[303,437],[451,-117],[175,14],[687,293],[1114,7],[196,439],[197,220],[-149,543],[65,939],[-251,387],[-359,220],[-141,6],[-254,175],[-306,427],[-679,624],[-92,31],[-522,409],[381,651],[-432,466],[-317,557],[-864,239],[80,195],[-294,230],[-181,-367],[-570,463],[-421,124],[-568,282],[-178,-140],[-290,-99],[-478,-661],[-541,199],[-502,-605],[23,-66],[-287,-353],[-362,-373],[-25,275],[-157,-214],[-336,-287],[-103,-540],[-255,-628],[-123,-46],[-176,109],[-104,-346],[-131,-75],[-417,174],[-883,821],[-147,355],[-43,473],[126,270],[-14,299],[-163,48],[-194,1241],[-211,754],[-497,1315],[707,648],[214,425],[129,88],[-334,388],[-387,356],[-221,291],[-221,420],[-83,619],[85,268],[5,358],[-341,947],[124,300],[-190,338],[-307,263],[201,528],[-381,87],[-177,-28],[-173,-191],[-93,-231],[-273,53],[-283,286],[-372,230],[-346,137],[-219,-87],[-530,114],[-161,357],[-323,434],[-18,238],[-415,256],[-215,280],[-408,96],[-628,-122],[200,534],[336,357],[49,342],[5,565],[-418,745],[-331,849],[-743,-226],[-516,-348],[-264,-229],[-146,-465],[31,-410],[-13,-482],[-419,-116],[-68,-413],[13,-446],[-175,-708],[-45,-1365],[418,-693],[379,-433],[139,-385],[67,-763],[-180,-1499],[-174,-522],[-25,-829],[318,123],[317,-1],[238,-124],[157,-238],[-753,-1195],[-834,-738],[87,-163],[390,-438],[-481,-788]],[[36164,89578],[745,55],[-44,306],[63,224],[582,-293],[111,122],[519,270],[21,-132],[552,69],[458,144],[697,157],[102,-96],[811,150],[559,77],[243,-26],[422,-131],[123,-84],[518,279],[100,-446],[242,-463],[213,-261],[58,-177],[211,-246],[258,138],[-22,62],[345,276],[214,-516],[427,96]],[[44692,89132],[-86,285],[-341,722],[-133,484],[0,380],[127,862],[104,-21],[565,275],[323,468],[23,711],[297,1603],[-419,316],[-482,129],[7,190],[185,413],[-57,291],[-569,495],[-429,616],[-535,256],[-825,194],[-594,17],[-817,184],[-548,-245],[-1121,-1468],[-231,334],[-342,311],[-526,876],[-1647,-1021],[-696,-140],[-251,-79],[-13,77],[117,754],[-165,185],[-67,597],[-268,426],[-119,477],[-201,95],[-380,-37],[-315,379],[-186,476],[-438,-742],[-439,-468],[-259,-1209],[13,-370],[-34,-944],[43,-930],[-12,-542],[-76,-1008],[153,-272],[201,215],[379,-162],[709,-355],[711,-181],[598,-356],[-102,-996],[338,-774],[93,-778],[209,-549]],[[42702,55597],[-408,17],[98,555],[-202,384],[-80,634],[4,441],[-149,572],[307,464],[-364,234],[-117,652],[-443,-51],[-347,-183],[-260,-295],[-355,704],[-353,413],[-109,293],[137,39],[-271,1132],[-140,391],[471,570],[-571,542],[-287,352],[-114,596],[-189,374],[-317,363],[-76,206],[61,268],[125,175],[231,136],[-27,228],[210,793],[-226,120],[-295,338],[-206,119],[-228,738],[-195,268],[-137,76],[-376,39],[-799,-153],[-445,-170],[-478,-128],[-397,116],[-248,195],[-254,387],[-224,-123],[-58,-169],[290,-226],[-606,-34],[-310,-73],[-321,17],[-227,74],[-310,180],[-250,234],[-192,275],[-251,212],[-257,128],[-79,449],[-315,470],[-343,364]],[[33789,45957],[149,459],[255,159],[259,-14],[347,-280],[184,-73],[525,-47],[372,-267],[427,181],[250,159],[203,208],[129,225],[324,428],[660,547],[-169,424],[45,656],[91,531],[211,494],[57,278],[-170,762],[-191,582],[-9,682],[-48,541],[597,94],[703,-74],[254,5],[738,173],[350,143],[408,82],[184,191],[683,546],[258,266],[329,2],[300,329],[230,76],[362,5],[-173,458],[-208,280],[110,255],[-113,174]],[[30224,44901],[57,-159],[132,-12],[403,151],[554,573],[451,221],[522,-47],[300,144],[201,203],[345,81],[600,-99]],[[31430,70319],[-255,-144],[-406,-670],[-447,-781],[-279,-348],[-218,-431],[-197,-471],[-175,-515],[-67,-330],[-5,-875]],[[34196,2070],[-334,216],[321,706],[-100,50],[187,445],[-389,235],[228,504],[191,231],[-10,143],[225,221],[48,270],[-65,384],[37,130],[219,202],[38,468],[94,104],[-23,220],[-124,62],[-9,334],[92,131],[-31,411],[55,259],[144,297],[-207,6],[282,444],[141,106],[80,368],[-328,-63],[-53,-119],[-160,299],[-53,266],[-196,-44],[-11,164],[-124,42],[25,192],[-400,116],[-66,157],[-364,271],[-376,-148],[430,406],[-708,182],[-740,65],[-719,120],[233,1150],[-110,146],[-764,471],[-325,328],[-585,334],[-629,90],[-732,207]],[[28531,13649],[-384,-163],[134,-493],[71,-565],[72,98],[90,-472],[-563,-208],[-162,-302],[245,-178],[-31,-210],[266,-160],[26,-500],[154,61],[623,-371],[130,-159],[-56,-219],[-492,113],[-34,-156],[-128,-61],[36,-236],[-400,-401],[17,-222],[356,-144],[595,-170],[203,154],[567,-76],[170,143],[258,-58],[251,-222],[22,-145],[-162,-333],[239,-234],[-123,-402],[-383,-63],[-405,-276],[-186,-219],[781,-896],[335,-542],[386,-834],[254,-810],[152,-861],[54,-533],[33,-677],[215,-537],[588,-904],[227,-167],[269,-37],[315,123],[188,196],[438,805],[414,944]],[[32639,17620],[-99,50],[-102,-477],[26,-617],[-77,-344],[-49,36],[-499,-438],[-512,-279],[-395,152],[-212,21],[-454,-354]],[[30266,15370],[1508,-2190],[140,-53],[430,105],[373,540],[375,222],[359,-41],[63,772],[-7,325],[-138,40],[136,944],[-383,359],[-30,747],[-453,480]],[[40597,17348],[-1050,1394],[-423,-846],[-370,-531],[112,-170],[281,-693]],[[39147,16502],[1000,414],[173,99],[277,333]],[[48206,81395],[-449,-769],[-476,333],[-370,121],[-191,539],[-183,402],[-209,804],[-1200,1449],[-15,839],[123,376],[211,421],[185,829],[68,457],[160,486],[52,362],[-973,320],[-8,440],[-75,365],[-164,-37]],[[34533,78396],[234,-356],[413,-471],[307,241],[358,157],[916,192],[428,219],[-74,-188],[21,-779],[106,-136],[250,-141],[355,-27],[323,107],[415,-135],[274,31],[229,-279],[423,-266],[789,-944],[337,-318],[281,-682],[44,41],[184,-243],[625,-437],[67,-364],[102,-250],[534,-530],[379,293],[180,430],[361,279],[-473,1042],[720,114],[176,-37],[573,269],[222,39],[76,-93],[100,-447],[102,3],[75,-808],[661,55],[359,108],[195,148],[66,966],[499,-203],[675,-507]],[[33870,88070],[259,-589],[-46,-615],[-5,-447],[-139,-472],[-10,-380],[295,-797],[-46,-758],[196,-897],[69,-208],[282,-1352],[-163,-1374],[-40,-696],[11,-1089]],[[36164,89578],[-697,-523],[-399,-165],[-704,-382],[-494,-438]],[[33789,45957],[-50,-763],[291,-1097],[296,176],[221,-293],[424,-284],[276,258],[89,12],[150,-262],[37,52],[239,-266],[202,-323],[486,-118],[223,-192],[110,-173],[239,152],[305,365],[1466,1369],[865,511],[411,-277],[140,146],[336,860],[66,-38],[419,1364],[1058,-25],[774,-166],[-84,-595],[-49,-59],[-20,-413],[67,-112],[75,426],[158,366],[163,571],[72,-115],[260,-112],[130,1031],[53,274],[144,382],[328,560],[111,263],[121,86],[200,-191],[176,-72],[227,-362],[36,-234],[129,-242],[214,-219],[166,-49],[251,65],[727,456],[315,285],[179,303],[177,631],[29,372],[-50,368],[-176,593],[-509,2584],[-10,356],[104,332],[111,164]],[[46687,54638],[-136,167],[-29,316],[-281,247],[-342,409],[-398,174],[-390,16],[-327,205],[-187,-175],[-572,-4],[-175,-72],[-295,-10],[-541,-149],[-312,-165]],[[34196,2070],[251,575],[577,1209],[120,408],[263,1159],[30,214],[77,1341],[94,563],[314,983],[106,212],[240,275],[379,184],[707,147],[269,240],[79,459],[-65,383],[-300,860],[-250,958],[-75,603],[10,668],[32,268],[131,535],[197,509],[259,462],[538,649],[527,376],[441,192]],[[30266,15370],[-246,-250],[-693,-458],[-333,-530],[-255,-169],[-208,-314]],[[40597,17348],[136,349],[25,387],[-142,676],[-11,674],[160,1122],[100,378],[-636,201],[-144,-753],[-167,-527],[28,-232],[-237,-429],[-237,148],[-274,51],[-393,-355],[-140,-235],[-193,-187],[-205,-1045],[-147,-385],[-652,123],[-401,128],[-159,-6],[-420,-521],[-261,441],[-321,452],[-221,144],[-288,-32],[-458,-208],[-202,-189],[-418,344],[-150,166],[-197,375],[-256,-122],[-321,6],[-400,-310],[-356,-357]],[[29116,73181],[-206,-245],[-191,-371],[-31,-556],[790,-549],[294,-405],[896,-641],[612,301],[150,-396]],[[30253,76159],[-200,-760],[216,-559],[46,-633],[-502,-655],[-697,-371]],[[34533,78396],[-756,-704],[-181,-287],[-142,-322],[35,-218],[-104,-510],[-331,-445],[-722,262],[-310,296],[-357,-196],[-389,-150],[-358,41],[-364,108],[-301,-112]],[[46687,54638],[131,-160],[113,123],[369,154],[571,44],[1353,439],[275,131],[594,399],[184,31],[575,-163],[238,-156],[1077,-1026],[510,-590],[275,-273],[909,-791],[283,-213],[304,-166],[317,-115],[188,649],[-9,466],[-329,36],[-601,468],[53,420],[-286,8],[-5,291],[269,1],[1159,296],[638,36],[-76,434],[343,169],[575,534],[88,-84],[149,131],[81,218],[32,375],[-9,501],[468,-112],[17,209],[-632,2641],[-1613,1130],[-315,2142],[569,-355],[384,-345],[249,-139],[230,-54],[165,152],[231,356],[198,162],[322,46],[441,156],[-6,-94],[320,-54],[429,-132],[17,-248],[-235,-118],[-70,-365],[253,-276],[510,-299],[73,-123],[528,-51],[200,148],[640,213],[-1,334],[-102,182],[-44,364],[581,331],[809,366],[239,132],[165,352]],[[24142,85016],[-47,-357],[-399,-626],[-163,-122],[-168,-405],[-292,343],[-398,-160],[-401,-71],[-83,-686],[-319,-170],[94,-369],[-190,-33],[161,-453],[76,48],[247,-962],[182,-283],[523,-442],[227,-369],[143,8],[439,-168],[398,-207],[289,-106],[410,-11],[473,-92],[593,-1119],[572,-721],[325,158],[1029,122],[459,-137],[1087,-512],[64,-155],[508,-77],[275,53],[-3,-776]],[[33870,88070],[-66,163],[-675,-182],[102,696],[-24,351],[-164,-43],[-209,95],[-332,451],[-203,149],[-378,455],[-201,154],[-727,285],[-521,-416],[-1009,-419],[-392,-357],[-501,-55],[-694,-426],[-511,-283],[-665,-698],[-360,-7],[-473,-66],[-432,44],[-190,-394],[-434,-522],[-157,-287],[-168,-437],[-164,-652],[-123,-196],[-57,-457]],[[24142,85016],[-159,26],[-290,307],[-365,729],[-350,332],[-394,282],[-251,276],[-306,227],[-141,-619],[-197,-153],[-713,-109],[-389,-327],[-240,181],[-829,-477],[-244,-488],[-147,-126],[-235,-65],[-221,150],[-708,200],[-150,133],[-273,458],[-492,-500],[-360,-226],[-181,-176],[-276,-402],[-250,-629],[-415,-349],[-293,-398],[-321,-355],[-495,-332],[-233,-256],[-490,-998],[-315,-811],[-143,-464],[-132,-604],[-121,-806],[-91,-286],[-286,-436],[-587,-511],[-281,-166],[-585,-227],[-219,-141],[-150,-267],[-154,-437],[-21,-343],[108,-445],[20,-309],[-61,-250],[-179,-311],[117,-551],[-264,-267],[-382,-216],[-416,-562],[-198,-800],[120,-621],[8,-193],[227,-1108],[265,-677],[8,-232],[218,-134],[364,-32],[208,52],[163,-136],[-12,-388]],[[25079,70984],[204,516],[433,383],[325,211],[743,381],[860,533],[143,39],[386,-21],[209,44],[739,241],[-5,-130]],[[10963,68653],[613,43],[181,-132],[708,-231],[445,41],[334,151],[336,309],[473,250],[162,-8],[934,-615],[479,-386],[255,-653]],[[83337,69218],[-327,103],[-1243,518],[-228,-607],[-425,190],[-73,-189],[-77,62],[-286,-440],[-379,387],[-107,-135],[74,-83],[-215,-252],[67,-479],[-146,-17],[44,-180],[-199,-97],[-41,-362],[-307,-632],[-264,173],[-25,-104],[-243,198],[-417,127],[-19,-184],[248,-540],[-169,-43],[-154,-235],[-207,-430],[-37,16],[-510,-353],[-438,328],[-88,-503],[126,-358],[-60,-342],[216,7],[6,-170],[-143,-222],[132,-122],[256,-399],[163,-173],[-194,-221],[-100,-271],[-28,-513],[48,-233],[-381,-363],[29,-519],[-86,-386],[167,-35],[278,56],[55,-96],[345,-100],[190,-164],[592,-4],[592,-67],[268,-157],[409,-92],[237,19],[527,-151],[176,-15],[429,133],[272,155],[257,-141],[165,-208],[215,-43]],[[82304,60260],[129,804],[-568,149],[-29,529],[22,235],[-78,17],[37,641],[-35,644],[284,184],[238,331],[-492,419],[108,68],[127,242],[-131,122],[427,878],[381,-250],[721,904],[-165,344],[-341,304],[-231,129],[-87,185],[313,488],[281,611],[219,392],[-97,588]],[[84840,50166],[537,-405],[187,-103],[303,14],[854,339],[360,74],[244,-26],[877,-358],[650,-360],[465,-308],[301,-80],[368,-17],[348,-172],[505,-461],[364,-265],[426,-444]],[[93864,60177],[-328,-132],[-240,26],[-292,-198],[-185,-380],[-238,-156],[-251,-28],[-260,109],[-102,-120],[331,-265],[-203,-335],[18,-288],[172,-51],[-215,-316],[-160,18],[75,-210],[46,-380],[197,-143],[244,-49],[129,-473],[-260,-158],[-117,9],[-561,-222],[-271,-62],[-102,-95],[82,-694],[141,-367],[59,-365],[-48,-200],[-366,-278],[-403,83],[-368,126],[-255,278],[-285,-365],[-182,-319],[-64,412],[-1314,-423],[-29,178],[-746,-124],[-63,-402],[-193,10],[84,699],[89,291],[-81,174],[-354,-146],[7,-343],[-381,-1370],[68,-264],[-94,-232],[-201,-65],[-382,-322],[-185,66],[-223,-167],[-190,-562],[-48,-485],[-102,-394],[-424,-542]],[[94643,51484],[-184,41],[-34,225],[258,289],[-28,83],[-209,-29],[100,1157],[186,23],[273,240],[-127,98],[150,526],[612,507],[-114,305],[116,-17],[110,562],[136,288],[20,255],[-219,281],[-421,426],[-326,-5],[-104,-133],[-403,182],[26,566],[181,238],[-70,356],[439,-188],[261,-22],[223,99],[339,361],[117,219],[304,-269],[141,51],[17,-646],[89,-92],[66,250],[299,127],[174,481],[663,-783],[-218,-633],[-288,-28],[57,-235],[-268,-368],[-17,-154],[117,-149],[226,125],[354,439],[338,57],[318,-83],[132,136],[272,-239],[157,48],[557,309],[56,74],[159,598],[129,333],[-515,509],[-178,321],[-180,447],[-130,-53],[-114,561],[-201,14],[-77,128],[448,394],[232,369],[-373,392],[-199,-117],[-223,57],[-200,269],[-161,-45],[-198,73],[-513,-106],[-134,-137],[-524,-307],[-511,42],[-178,136],[-287,-50],[-367,132],[-284,-55],[-214,-213],[-480,-109],[-78,-105],[-282,-136]],[[91629,47594],[297,539],[257,-221],[144,220],[-195,181],[-50,267],[219,279],[97,28],[343,-248],[193,474],[146,-202],[239,375],[409,445],[300,98],[326,515],[265,602],[70,339],[-46,199]],[[93864,60177],[-79,428],[-195,493],[-128,564],[-86,-7],[-65,536],[-36,1013],[-552,378],[-459,-34],[-74,276],[-632,146],[-488,226],[-284,-16],[-105,295],[-387,-313],[-376,-566],[37,-187],[-445,-128],[-515,-232],[-375,-22],[-166,248],[104,219],[-248,88],[-695,130],[-26,203],[467,483],[207,117],[142,291],[562,594],[143,331],[-190,325],[-289,-55],[-851,-308],[-302,-83],[-445,1002],[-632,998],[-189,361],[-427,220],[-472,90],[-775,-53],[18,322],[146,221],[873,665],[222,262],[139,250],[0,176],[-138,172],[266,271],[-319,191],[-454,100],[-66,410],[-180,447],[-76,490],[85,961],[-197,442],[-300,-4],[31,-285],[-184,-62],[26,-258],[-1090,-265],[76,-322],[-676,-306],[19,-157],[389,-1586],[163,-460],[26,-685]],[[82304,60260],[307,-299],[106,30],[47,-154],[207,-143],[158,44],[24,-302],[181,-630],[23,-588],[-91,-467],[-105,-214],[760,-205],[616,-108],[476,81],[391,-477],[200,-299],[226,-439],[-515,-546],[-312,-162],[-162,-23],[-516,234],[-604,-136],[-57,-279],[-263,-375],[-352,-827],[4,-393],[-125,-443],[-41,-601],[-177,-248],[-52,-388],[-78,-244],[-187,-816],[70,-516],[186,-551],[106,-177],[198,-605],[311,132],[207,159],[607,674],[210,169],[367,81],[185,-43]],[[91629,47594],[252,-298],[225,-429],[68,-243],[52,-591],[89,-403],[161,-454],[123,-180],[249,-163],[995,-325],[241,-114],[397,-313],[671,-290],[272,-247],[-185,-476],[-194,-227],[-125,-327],[-523,-861],[-189,-376],[-244,162],[-148,-295],[192,-302],[-433,-312],[193,-150],[-54,-158],[664,-475],[147,354],[341,-274],[1332,-401],[366,826],[-55,57],[217,463],[23,175],[979,862],[367,-40],[1153,-766],[619,406],[-4,2110],[136,38],[-277,1724],[-257,1437],[5,196],[-105,442],[-370,294],[-228,273],[-500,1179],[-111,443],[-741,903],[-831,786],[-203,78],[-707,-113],[-574,217],[-457,68]],[[15923,55151],[-230,416],[-362,480],[-653,-671],[-652,848],[296,425],[-494,599],[394,494],[-473,566],[76,68],[-716,977],[-102,230],[-93,402],[120,57],[-93,277],[168,230],[-252,56],[-246,125],[-244,273],[-185,74],[-262,281],[133,259],[352,355],[-131,126],[217,362],[-96,115],[26,173],[-427,571],[-412,847],[-215,909],[-257,787],[-564,162]],[[3472,50849],[327,-64],[540,204],[275,147],[790,173],[224,220],[169,310],[502,428],[341,-446],[166,-365],[186,507],[205,425],[242,-205],[108,197],[198,-225],[350,371],[145,-13],[259,163],[-46,-174],[105,-128],[266,281],[-203,-446],[113,-144],[405,135],[258,-233],[193,253],[317,-333],[-353,-528],[685,-861],[876,-1199],[828,518],[520,259],[-217,527],[177,-61]],[[10546,66024],[-1555,274],[-273,3],[-206,-70],[-785,-780],[-292,-534],[369,-442],[-49,-276],[-761,241],[-339,-141],[-271,-249],[-274,-507],[-278,-306],[-166,-349],[-457,-427],[-722,-890],[-161,169],[-537,-411],[-553,-474],[-206,257],[-267,-166],[-170,162],[-583,-1345],[-1014,-1369],[-279,-471],[-520,-1208],[-197,-390],[131,-117],[253,-841],[276,9],[348,-89],[228,-205],[331,-149],[202,-346],[1138,-2061],[176,-864],[389,-813]],[[10963,68653],[-507,-811],[33,-462],[-95,-943],[232,-171],[-80,-242]],[[3458,50838],[-495,-421],[-152,-624],[-293,-553],[-56,99],[-245,-167],[-1120,-255],[-303,-316],[-347,-782],[-153,-800],[137,-456],[345,-532],[388,-961],[561,-1095],[595,-60],[457,111],[1367,194],[323,-466],[264,-164],[358,-374],[841,-813],[283,-462],[424,-561],[291,-817],[426,5],[181,-376],[415,-221],[321,-261],[472,-492],[813,338]],[[9556,39556],[-288,512],[-170,239],[525,202],[-132,408],[-1663,1315],[-85,81],[475,281],[-36,62],[-668,620],[-3,29],[585,832],[-436,380],[257,331],[-461,484],[238,467],[-742,745],[-47,114],[-495,459],[-52,-131],[-490,221],[-206,34],[19,302],[-308,469],[-394,503],[-248,50],[-289,297],[-73,342],[-423,-394],[-97,-19],[61,432],[12,511],[-56,296],[-117,270],[61,152],[-113,224],[-239,162]],[[3472,50849],[-14,-11]],[[9556,39556],[329,127],[339,-89],[326,7],[705,-644],[70,-137],[198,104],[-33,88],[293,248],[105,-51],[512,747],[257,283],[151,-225],[245,330],[93,267],[252,-471],[-230,-1224],[-321,-1084],[-140,-657],[257,-719],[94,-640],[153,-376],[111,-612],[129,-344],[304,-386],[318,-472],[465,-279],[281,-65],[131,352],[581,89],[245,107],[-187,157],[-284,140],[-149,173],[-517,-59],[-166,107],[-167,286],[-26,180],[108,124],[237,38],[449,212],[611,549],[27,109],[-96,404],[-247,226],[-500,151],[-109,143],[-73,363],[-15,326],[146,227],[571,172],[845,-323],[55,-341],[127,-223],[208,-131],[-50,-338],[-114,-152],[16,-226],[178,-296],[111,-292],[507,-61],[468,457],[290,-270],[225,-582],[-44,-131],[200,-56],[242,226],[154,-331],[414,-2],[-146,370],[16,788],[-38,434],[-70,308],[150,-116],[352,-45],[736,-29],[218,-73],[-139,405],[249,51],[517,-13],[1243,-225],[248,198],[128,-84],[49,128],[481,89],[531,-220],[660,-416],[647,-316],[218,-45],[764,199],[686,250],[415,-67],[330,834],[-14,253],[72,270],[194,193],[-180,157],[-62,342],[-101,163],[-252,230],[-43,268],[-174,429],[-156,106],[-219,360],[-26,188],[82,331],[126,276],[-200,258],[-230,119],[-239,945]]],"transform":{"scale":[0.005976723635066643,-0.004800048000480004],"translate":[181.16680660848533,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/so.json b/src/onegov/election_day/static/mapdata/2025/so.json new file mode 100644 index 0000000000..dc1679621f --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/so.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":2401,"properties":{"id":2401,"name":"Egerkingen"},"arcs":[[-1,-2,-3,-4,-5,-6,-7]]},{"type":"Polygon","id":2402,"properties":{"id":2402,"name":"Härkingen"},"arcs":[[-8,0,-9,-10]]},{"type":"Polygon","id":2403,"properties":{"id":2403,"name":"Kestenholz"},"arcs":[[-11,-12,-13,-14,-15]]},{"type":"Polygon","id":2404,"properties":{"id":2404,"name":"Neuendorf"},"arcs":[[-16,-17,-18,1,7,-19]]},{"type":"Polygon","id":2405,"properties":{"id":2405,"name":"Niederbuchsiten"},"arcs":[[-20,11,-21,16]]},{"type":"Polygon","id":2406,"properties":{"id":2406,"name":"Oberbuchsiten"},"arcs":[[-22,-23,-24,2,17,20,10]]},{"type":"Polygon","id":2407,"properties":{"id":2407,"name":"Oensingen"},"arcs":[[-25,21,14,-26]]},{"type":"Polygon","id":2408,"properties":{"id":2408,"name":"Wolfwil"},"arcs":[[-27,-28,12,19,15]]},{"type":"Polygon","id":2421,"properties":{"id":2421,"name":"Aedermannsdorf"},"arcs":[[-29,-30,-31,-32,-33,-34]]},{"type":"Polygon","id":2422,"properties":{"id":2422,"name":"Balsthal"},"arcs":[[-35,-36,22,24,-37,-38]]},{"type":"Polygon","id":2424,"properties":{"id":2424,"name":"Herbetswil"},"arcs":[[-39,-40,32,-41,-42,-43]]},{"type":"Polygon","id":2425,"properties":{"id":2425,"name":"Holderbank (SO)"},"arcs":[[-44,-45,3,23,35]]},{"type":"Polygon","id":2426,"properties":{"id":2426,"name":"Laupersdorf"},"arcs":[[37,-46,-47,-48]]},{"type":"Polygon","id":2427,"properties":{"id":2427,"name":"Matzendorf"},"arcs":[[30,-49,46,-50]]},{"type":"Polygon","id":2428,"properties":{"id":2428,"name":"Mümliswil-Ramiswil"},"arcs":[[47,48,29,-51,-52,43,34]]},{"type":"Polygon","id":2430,"properties":{"id":2430,"name":"Welschenrohr-Gänsbrunnen"},"arcs":[[38,-53,-54,-55,-56,-57]]},{"type":"Polygon","id":2445,"properties":{"id":2445,"name":"Biezwil"},"arcs":[[-58,-59,-60,-61]]},{"type":"Polygon","id":2455,"properties":{"id":2455,"name":"Lüterkofen-Ichertswil"},"arcs":[[-62,-63,-64,-65,-66]]},{"type":"Polygon","id":2457,"properties":{"id":2457,"name":"Messen"},"arcs":[[-67,58,-68,-69,-70]]},{"type":"Polygon","id":2461,"properties":{"id":2461,"name":"Schnottwil"},"arcs":[[-71,59,66]]},{"type":"Polygon","id":2463,"properties":{"id":2463,"name":"Unterramsern"},"arcs":[[-72,-73,68]]},{"type":"Polygon","id":2464,"properties":{"id":2464,"name":"Lüsslingen-Nennigkofen"},"arcs":[[65,-74,-75,-76,-77,-78]]},{"type":"Polygon","id":2465,"properties":{"id":2465,"name":"Buchegg"},"arcs":[[67,57,-79,63,-80,71]]},{"type":"Polygon","id":2471,"properties":{"id":2471,"name":"Bättwil"},"arcs":[[-81,-82,-83]]},{"type":"Polygon","id":2472,"properties":{"id":2472,"name":"Büren (SO)"},"arcs":[[-84,-85,-86,-87,-88]]},{"type":"Polygon","id":2473,"properties":{"id":2473,"name":"Dornach"},"arcs":[[-89,-90,-91]]},{"type":"Polygon","id":2474,"properties":{"id":2474,"name":"Gempen"},"arcs":[[-92,84,-93,88,-94]]},{"type":"Polygon","id":2475,"properties":{"id":2475,"name":"Hochwald"},"arcs":[[-95,-96,89,92,83]]},{"type":"Polygon","id":2476,"properties":{"id":2476,"name":"Hofstetten-Flüh"},"arcs":[[-97,-98,82,-99,-100]]},{"type":"Polygon","id":2477,"properties":{"id":2477,"name":"Metzerlen-Mariastein"},"arcs":[[-101,-102,96,-103]]},{"type":"Polygon","id":2478,"properties":{"id":2478,"name":"Nuglar-St. Pantaleon"},"arcs":[[85,91,-104]]},{"type":"Polygon","id":2479,"properties":{"id":2479,"name":"Rodersdorf"},"arcs":[[-105,100]]},{"type":"Polygon","id":2480,"properties":{"id":2480,"name":"Seewen"},"arcs":[[-106,94,87,-107,-108,-109]]},{"type":"Polygon","id":2481,"properties":{"id":2481,"name":"Witterswil"},"arcs":[[81,-110,98]]},{"type":"Polygon","id":2491,"properties":{"id":2491,"name":"Hauenstein-Ifenthal"},"arcs":[[-111,-112,-113,-114,-115,-116]]},{"type":"Polygon","id":2492,"properties":{"id":2492,"name":"Kienberg"},"arcs":[[-117,-118]]},{"type":"Polygon","id":2493,"properties":{"id":2493,"name":"Lostorf"},"arcs":[[-119,-120,-121,-122,-123,-124,-125]]},{"type":"Polygon","id":2495,"properties":{"id":2495,"name":"Niedergösgen"},"arcs":[[-126,-127,-128,-129,-130,118,-131]]},{"type":"Polygon","id":2497,"properties":{"id":2497,"name":"Obergösgen"},"arcs":[[-132,119,129,-133,-134]]},{"type":"Polygon","id":2499,"properties":{"id":2499,"name":"Stüsslingen"},"arcs":[[130,124,-135,-136]]},{"type":"Polygon","id":2500,"properties":{"id":2500,"name":"Trimbach"},"arcs":[[114,-137,121,-138,-139,-140]]},{"type":"Polygon","id":2501,"properties":{"id":2501,"name":"Winznau"},"arcs":[[-141,-142,137,120,131]]},{"type":"Polygon","id":2502,"properties":{"id":2502,"name":"Wisen (SO)"},"arcs":[[122,136,113,-143]]},{"type":"Polygon","id":2503,"properties":{"id":2503,"name":"Erlinsbach (SO)"},"arcs":[[135,-144,116,-145,-146,-147,125]]},{"type":"MultiPolygon","id":2511,"properties":{"id":2511,"name":"Aeschi (SO)"},"arcs":[[[-148,-149,-150,-151]],[[-152]]]},{"type":"Polygon","id":2513,"properties":{"id":2513,"name":"Biberist"},"arcs":[[-153,-154,-155,-156,-157,76,-158,-159]]},{"type":"Polygon","id":2514,"properties":{"id":2514,"name":"Bolken"},"arcs":[[149,-160,-161,-162]]},{"type":"Polygon","id":2516,"properties":{"id":2516,"name":"Deitingen"},"arcs":[[-163,-164,-165,-166,-167,-168]]},{"type":"Polygon","id":2517,"properties":{"id":2517,"name":"Derendingen"},"arcs":[[167,-169,-170,-171,-172,153,-173,-174]]},{"type":"Polygon","id":2518,"properties":{"id":2518,"name":"Etziken"},"arcs":[[-175,159,148,-176,-177]]},{"type":"Polygon","id":2519,"properties":{"id":2519,"name":"Gerlafingen"},"arcs":[[154,171,-178,-179,-180]]},{"type":"Polygon","id":2520,"properties":{"id":2520,"name":"Halten"},"arcs":[[-181,-182,-183,-184]]},{"type":"Polygon","id":2523,"properties":{"id":2523,"name":"Horriwil"},"arcs":[[-185,-186,175,-187,-188]]},{"type":"Polygon","id":2524,"properties":{"id":2524,"name":"Hüniken"},"arcs":[[176,185,-189]]},{"type":"Polygon","id":2525,"properties":{"id":2525,"name":"Kriegstetten"},"arcs":[[170,-190,181,-191,-192,177]]},{"type":"Polygon","id":2526,"properties":{"id":2526,"name":"Lohn-Ammannsegg"},"arcs":[[77,156,-193,61]]},{"type":"Polygon","id":2527,"properties":{"id":2527,"name":"Luterbach"},"arcs":[[173,-194,-195,162]]},{"type":"Polygon","id":2528,"properties":{"id":2528,"name":"Obergerlafingen"},"arcs":[[178,191,-196,-197]]},{"type":"Polygon","id":2529,"properties":{"id":2529,"name":"Oekingen"},"arcs":[[189,169,-198,187,-199,182]]},{"type":"Polygon","id":2530,"properties":{"id":2530,"name":"Recherswil"},"arcs":[[-200,-201,195,190,180]]},{"type":"Polygon","id":2532,"properties":{"id":2532,"name":"Subingen"},"arcs":[[-202,160,174,188,184,197,168,166]]},{"type":"Polygon","id":2534,"properties":{"id":2534,"name":"Zuchwil"},"arcs":[[152,-203,-204,-205,193,172]]},{"type":"Polygon","id":2535,"properties":{"id":2535,"name":"Drei Höfe"},"arcs":[[183,198,186,147,-206,199]]},{"type":"Polygon","id":2541,"properties":{"id":2541,"name":"Balm bei Günsberg"},"arcs":[[42,-207,-208,-209,52]]},{"type":"Polygon","id":2542,"properties":{"id":2542,"name":"Bellach"},"arcs":[[-210,157,75,-211,-212,-213,-214]]},{"type":"Polygon","id":2543,"properties":{"id":2543,"name":"Bettlach"},"arcs":[[-215,-216,-217]]},{"type":"Polygon","id":2544,"properties":{"id":2544,"name":"Feldbrunnen-St. Niklaus"},"arcs":[[203,-218,-219,-220]]},{"type":"Polygon","id":2545,"properties":{"id":2545,"name":"Flumenthal"},"arcs":[[-221,164,-222,-223]]},{"type":"Polygon","id":2546,"properties":{"id":2546,"name":"Grenchen"},"arcs":[[-224,214,-225]]},{"type":"Polygon","id":2547,"properties":{"id":2547,"name":"Günsberg"},"arcs":[[-226,-227,206,41,-228,-229]]},{"type":"Polygon","id":2548,"properties":{"id":2548,"name":"Hubersdorf"},"arcs":[[-230,-231,222,-232,225]]},{"type":"Polygon","id":2549,"properties":{"id":2549,"name":"Kammersrohr"},"arcs":[[228,-233,229]]},{"type":"Polygon","id":2550,"properties":{"id":2550,"name":"Langendorf"},"arcs":[[213,-234,-235,-236]]},{"type":"Polygon","id":2551,"properties":{"id":2551,"name":"Lommiswil"},"arcs":[[211,-237,-238]]},{"type":"Polygon","id":2553,"properties":{"id":2553,"name":"Oberdorf (SO)"},"arcs":[[237,-239,54,-240,233,212]]},{"type":"Polygon","id":2554,"properties":{"id":2554,"name":"Riedholz"},"arcs":[[231,221,163,194,204,219,-241,207,226]]},{"type":"Polygon","id":2555,"properties":{"id":2555,"name":"Rüttenen"},"arcs":[[234,239,53,208,240,218,-242]]},{"type":"Polygon","id":2556,"properties":{"id":2556,"name":"Selzach"},"arcs":[[-243,55,238,236,210,74,-244,215,223]]},{"type":"Polygon","id":2571,"properties":{"id":2571,"name":"Boningen"},"arcs":[[-245,-246,-247,-248,-249]]},{"type":"Polygon","id":2572,"properties":{"id":2572,"name":"Däniken"},"arcs":[[128,-250,-251,-252,132]]},{"type":"Polygon","id":2573,"properties":{"id":2573,"name":"Dulliken"},"arcs":[[133,251,-253,-254,-255,-256,140]]},{"type":"Polygon","id":2574,"properties":{"id":2574,"name":"Eppenberg-Wöschnau"},"arcs":[[145,-257,-258]]},{"type":"Polygon","id":2575,"properties":{"id":2575,"name":"Fulenbach"},"arcs":[[18,9,244,-259,26]]},{"type":"Polygon","id":2576,"properties":{"id":2576,"name":"Gretzenbach"},"arcs":[[-260,249,127,-261,-262]]},{"type":"Polygon","id":2578,"properties":{"id":2578,"name":"Gunzgen"},"arcs":[[6,-263,-264,245,8]]},{"type":"Polygon","id":2579,"properties":{"id":2579,"name":"Hägendorf"},"arcs":[[-265,111,-266,-267,262,5]]},{"type":"Polygon","id":2580,"properties":{"id":2580,"name":"Kappel (SO)"},"arcs":[[263,266,-268,-269,-270,246]]},{"type":"Polygon","id":2581,"properties":{"id":2581,"name":"Olten"},"arcs":[[-271,-272,247,269,-273,138,141,255]]},{"type":"Polygon","id":2582,"properties":{"id":2582,"name":"Rickenbach (SO)"},"arcs":[[-274,267,265,110]]},{"type":"Polygon","id":2583,"properties":{"id":2583,"name":"Schönenwerd"},"arcs":[[257,-275,260,126,146]]},{"type":"Polygon","id":2584,"properties":{"id":2584,"name":"Starrkirch-Wil"},"arcs":[[270,254,-276]]},{"type":"Polygon","id":2585,"properties":{"id":2585,"name":"Walterswil (SO)"},"arcs":[[-277,252,250,259]]},{"type":"Polygon","id":2586,"properties":{"id":2586,"name":"Wangen bei Olten"},"arcs":[[115,139,272,268,273]]},{"type":"Polygon","id":2601,"properties":{"id":2601,"name":"Solothurn"},"arcs":[[217,202,158,209,235,241]]},{"type":"Polygon","id":2611,"properties":{"id":2611,"name":"Bärschwil"},"arcs":[[-278,-279]]},{"type":"Polygon","id":2612,"properties":{"id":2612,"name":"Beinwil (SO)"},"arcs":[[-280,-281,-282,-283,50,28,-284]]},{"type":"Polygon","id":2613,"properties":{"id":2613,"name":"Breitenbach"},"arcs":[[-285,-286,-287,-288,-289]]},{"type":"Polygon","id":2614,"properties":{"id":2614,"name":"Büsserach"},"arcs":[[-290,-291,-292,-293,288,-294]]},{"type":"Polygon","id":2615,"properties":{"id":2615,"name":"Erschwil"},"arcs":[[279,-295,-296,290,-297]]},{"type":"Polygon","id":2616,"properties":{"id":2616,"name":"Fehren"},"arcs":[[293,287,-298,-299,-300]]},{"type":"Polygon","id":2617,"properties":{"id":2617,"name":"Grindel"},"arcs":[[-301,277,-302,291,295]]},{"type":"Polygon","id":2618,"properties":{"id":2618,"name":"Himmelried"},"arcs":[[108,-303,285,-304]]},{"type":"Polygon","id":2619,"properties":{"id":2619,"name":"Kleinlützel"},"arcs":[[-305]]},{"type":"Polygon","id":2620,"properties":{"id":2620,"name":"Meltingen"},"arcs":[[299,-306,-307,280,296,289]]},{"type":"Polygon","id":2621,"properties":{"id":2621,"name":"Nunningen"},"arcs":[[-308,297,286,302,107,-309,281,306]]},{"type":"Polygon","id":2622,"properties":{"id":2622,"name":"Zullwil"},"arcs":[[298,307,305]]}]}},"arcs":[[[66905,56060],[-154,329],[1759,1012],[-17,37],[917,537]],[[64496,56042],[55,40],[202,-296],[91,68],[213,-370],[105,61],[145,-225],[694,324],[178,-296],[502,154],[-193,292],[417,266]],[[62942,59732],[141,-353],[-59,-402],[98,-451],[330,-1008],[90,25],[954,-1501]],[[64796,61721],[129,-635],[-422,-53],[-298,-177],[77,-135],[-122,-324],[-283,-210],[-199,-5],[-169,-163],[-203,13],[-16,-161],[-167,34],[-181,-173]],[[65632,62044],[9,-126],[-845,-197]],[[69171,58461],[-254,431],[-194,649],[61,354],[-41,208],[-986,1194],[-419,616],[-78,184],[-891,214],[-737,-267]],[[69410,57975],[-23,154],[-216,332]],[[66905,56060],[256,-392],[-11,-247],[188,115],[307,-744],[161,67],[253,-625],[-256,-175],[312,-814],[151,47],[113,-261],[235,212],[244,-989],[786,-1773],[236,-889]],[[72495,51547],[-550,1166],[-510,1575],[-427,867],[-298,77],[-477,604],[74,184],[-671,1336],[56,33],[-282,586]],[[69880,49592],[2615,1955]],[[60458,52076],[-38,75],[-726,-434]],[[63217,46854],[-264,454],[-504,685],[-882,1457],[264,213],[-724,1325],[70,139],[-419,-101],[-462,950],[162,100]],[[61546,45006],[124,166],[538,263],[296,233],[1,196],[247,261],[465,729]],[[57707,43405],[659,-554],[263,-114],[669,409],[569,0],[524,-151],[286,264],[108,402],[162,380],[599,965]],[[59694,51717],[-1974,-1144],[579,-1197],[-299,-235],[-916,-885],[290,-355],[-220,-214],[215,-273],[-151,-144],[408,-509],[153,-1225],[-3,-267],[76,-1099],[-145,-765]],[[66613,48486],[259,172],[243,63],[526,-75],[1042,-512]],[[63937,52658],[196,-342],[141,52],[666,-1157],[530,-764],[221,-265],[159,-333],[154,-1],[75,-614],[254,-227],[239,-350],[41,-171]],[[64496,56042],[-639,-479],[-298,-391],[270,-409],[-188,-108],[235,-385],[210,41],[264,-520],[-501,-271],[318,-630],[-230,-232]],[[68683,48134],[1197,1458]],[[63217,46854],[517,321],[460,208],[374,99],[533,62],[363,100],[523,284],[626,558]],[[63937,52658],[-208,-142],[-209,429],[-290,498],[-357,-241],[-195,-74],[-134,256],[-2086,-1308]],[[56436,54845],[436,-307],[138,-438],[338,-400],[335,-292],[950,-614],[131,250],[318,-232],[143,-386],[171,113],[170,-341],[-79,-69],[207,-412]],[[58684,57614],[-409,-213],[-126,-421],[54,-481],[-437,-537],[-588,-520],[-380,-131],[-362,-466]],[[62942,59732],[-368,-277],[-96,91],[-352,-262],[-269,32],[-332,-139],[-1095,-294],[-303,114],[-558,-219],[-379,-87],[-355,-862],[-151,-215]],[[56436,54845],[-221,-86],[-363,-353],[-246,-171],[-390,-174],[-672,182],[-492,73],[-45,-199],[131,-127],[-96,-627],[-178,-224],[-296,-150],[-209,-226],[-183,18],[-332,-215],[-233,-5],[-321,87],[-187,-255],[-254,-125],[-62,-643],[-419,-154],[-264,29],[-309,-200],[-189,54],[-227,-45],[-459,25]],[[49920,51334],[28,-117],[323,-518],[181,-73],[19,-118],[1326,-750],[256,-219],[202,65],[445,-649],[-136,-174],[379,-595],[141,212],[344,-446],[-69,-187],[218,-218],[-107,-128],[185,-185],[-149,-184],[423,-423],[54,14],[420,603],[276,-299],[1109,-1351],[-125,-374],[114,-397],[482,-650],[629,-955],[819,187]],[[70723,44992],[-72,405],[-384,209],[-418,786],[-360,273],[153,136],[-405,693],[62,62],[-237,219],[-415,253],[36,106]],[[61546,45006],[1415,282],[103,-450],[77,-1050],[1268,-968],[237,-271],[220,426],[704,642],[177,194],[611,1076],[382,398],[214,118],[352,31],[120,-185],[-5,-600],[139,-284],[270,-215],[961,-364],[495,198],[265,299],[923,627],[249,82]],[[34260,60469],[-506,-405],[-146,-224],[-54,-297]],[[38712,60230],[-142,316],[-344,-200],[-296,103],[-283,-80],[-400,22],[-140,106],[-522,-322],[61,-520],[-283,-14],[-472,-189],[-708,-448],[-238,-97],[21,114],[-296,160],[-75,428],[-164,325],[-76,358],[-95,177]],[[39532,48269],[5,428],[207,297],[20,326],[152,475],[127,997],[-222,817],[-240,174],[352,434],[399,149],[-50,470],[-198,1376],[344,-12],[-178,483],[-241,259],[-148,361],[-158,89],[-417,396],[-120,255],[175,338],[-157,407],[-155,-7],[-69,456],[-429,941],[211,56],[326,327],[-173,132],[-190,683],[209,102],[44,259],[-246,493]],[[38672,48081],[860,188]],[[30105,56002],[43,-138],[286,34],[9,-193],[133,-289],[233,-312],[351,107],[193,133],[104,-45],[313,184],[132,323],[204,158],[704,757],[168,278],[280,287],[214,-776],[-257,-122],[-318,-415],[776,-850],[194,93],[323,-207],[412,-58],[106,-151],[282,-176],[196,-34],[275,-150],[183,50],[357,-104],[185,-197],[1077,-1384],[266,78],[208,-472],[310,-1041],[-598,-226],[-228,-265],[93,-171],[-99,-353],[77,-226],[-230,-502],[503,47],[259,88],[303,-356],[545,-1325]],[[33554,59543],[34,-92],[-74,-426],[-420,-650],[-1017,-683],[-487,218],[-1447,-1404],[-38,-504]],[[55469,61326],[-991,-800],[86,-189],[-51,-235],[58,-365],[-182,-341],[-183,-190],[-428,-280],[-455,-174],[-514,101],[-647,186],[-290,313],[-53,209],[45,401],[-358,299],[-172,34],[-771,379],[-228,-67],[-78,371],[-135,332],[-602,-31],[-343,-287],[-582,-37]],[[58684,57614],[-21,126],[-1166,-626],[-245,-101],[-1068,1627],[-715,2686]],[[48762,50167],[443,261],[183,240],[261,459],[271,207]],[[48595,60955],[179,-2522],[142,-1202],[-68,-146],[126,-82],[4,-247],[-78,-313],[184,-261],[-89,-361],[5,-281],[-626,22],[0,-337],[-78,24],[-191,-609],[43,-64],[-316,-1168],[523,-2294],[407,-947]],[[25253,50934],[376,-853],[408,72],[498,161],[953,183],[58,48],[875,303],[526,115],[134,-49],[317,82],[56,154],[444,-8],[23,-159],[307,-598],[215,89],[63,-78],[182,-624],[126,-144],[-12,-172],[463,-571],[-448,-252],[-384,-108],[-222,-606],[590,-123],[111,-123],[236,-610],[596,-879]],[[30105,56002],[-101,-1188],[-78,-354],[-84,-51],[102,-302],[-593,-571],[-546,-389],[113,-482],[-45,-305],[-136,-240],[-231,-233],[-598,-478],[-177,-57],[-535,-19],[-488,-109],[-534,52],[-921,-342]],[[34760,47174],[1337,312],[1615,394],[960,201]],[[33095,46392],[599,183],[439,203],[112,117],[515,279]],[[31744,46184],[522,230],[140,-61],[183,62],[276,-88],[95,190],[135,-125]],[[59549,63121],[-555,-401],[-986,-226],[-679,-134],[-466,-400],[-391,-186],[-366,-119],[-637,-329]],[[64796,61721],[-352,-82],[-8,245],[-415,147],[-387,-89],[-828,63],[-547,-169],[-179,33],[35,592],[-407,298],[-344,-24],[-1427,118],[-388,268]],[[45072,48728],[394,175],[578,352],[120,175],[244,179],[827,238],[372,262],[252,-281],[330,172],[173,0],[400,167]],[[41121,60771],[382,-1485],[388,-780],[69,-203],[412,-755],[229,-469],[614,-2032],[-26,-6],[316,-915],[90,47],[186,-524],[-231,-99],[42,-203],[161,69],[133,-393],[-145,-17],[261,-342],[279,-823],[84,-720],[518,-2166],[189,-227]],[[48595,60955],[-303,-8],[-648,112],[-435,-164],[-153,154],[-175,-24],[-429,285],[-192,-169],[-260,-60],[-516,33],[-1046,-200],[-792,-91],[-2,107],[-456,-43],[17,193],[-116,107],[-398,-44],[-90,-91],[-625,-276],[-436,-51],[-419,46]],[[41121,60771],[-129,-40],[-356,81],[-802,-223],[-1122,-359]],[[39532,48269],[803,81],[223,59],[1184,36],[417,-46],[496,66],[479,18],[548,-27],[956,59],[434,213]],[[44001,68407],[32,-220],[-369,14],[-11,-198],[216,-292],[-26,-246],[-109,-95],[87,-256],[58,-414],[-23,-336],[-860,-279],[64,-776],[-512,-297],[-1339,-627],[-458,-292],[-574,-294],[-167,-141],[-353,-60],[-711,-306],[-298,-327],[-464,-421],[-667,-327],[-757,-317],[-1312,-477],[-329,-197],[-108,-173],[-399,-249],[-352,-335]],[[59549,63121],[-1263,1251],[-1261,1875],[-753,2113],[-159,474],[-159,10],[-1495,357],[-365,102],[-202,1],[-583,158],[-955,195],[-2084,-304],[-1245,-163],[-661,-149],[-1176,-198],[-1525,-229],[-1662,-207]],[[25862,43379],[833,929],[439,419],[292,427],[382,329],[-245,19],[-70,107],[999,141],[152,-59],[316,80],[180,146],[772,254],[486,62],[369,-32],[242,37],[386,-88],[154,90],[195,-56]],[[25504,42792],[358,587]],[[16332,41372],[497,256],[648,231],[390,262],[142,-62],[664,223],[700,53],[167,-62],[889,-649],[487,-181],[835,-64],[434,57],[1374,420],[787,351],[1158,585]],[[11677,39345],[118,-38],[597,332],[235,317],[781,110],[146,-32],[401,257],[188,215],[578,447],[304,196],[492,-13],[559,227],[256,9]],[[25253,50934],[-114,-15],[-1131,-561],[-75,188],[-489,-242],[-539,-341],[-238,15],[-191,-130],[-101,83],[90,-320],[-135,-109],[-844,-442],[-194,-151],[-268,99],[-335,-507],[-455,-568],[-231,-234],[-352,-552],[-305,-843],[-311,-769],[-316,-581],[-187,-230],[-333,-299],[-421,-60],[-322,23],[-693,-190],[-584,-69],[-127,-98],[-553,-11],[-195,51],[-707,-51],[-514,-363],[-217,-262],[-467,-392],[-863,-580],[-1161,-356],[-206,-177],[-150,-381],[-22,-366],[148,-708],[137,-510],[395,-580]],[[14066,8077],[-158,422],[-190,339],[-172,452],[-155,833],[-395,488],[56,52],[-230,554],[-181,226]],[[10254,5457],[202,94],[398,290],[418,676],[844,571],[554,428],[128,195],[147,62],[581,70],[294,86],[246,148]],[[9470,10251],[126,-369],[-105,-127],[186,-400],[-320,-16],[104,-753],[294,-776],[-56,-169],[-68,-677],[102,-225],[7,-394],[-124,-64],[155,-219],[492,-228],[-104,-142],[95,-235]],[[12641,11443],[-413,-316],[-629,-201],[-86,159],[-750,-91],[64,-109],[-442,-95],[-311,-189],[-49,108],[-477,-494],[-78,36]],[[26480,20168],[-44,388],[-309,-74],[-151,692],[196,149],[-242,165],[-151,-23],[-229,380],[-84,259],[-197,-22],[-28,107],[108,472],[-185,6],[-65,522],[-234,-23],[-216,289]],[[26313,19683],[-191,59],[32,206],[344,51],[-18,169]],[[20204,18892],[194,-71],[155,85],[404,88],[166,-312],[233,5],[224,101],[54,-210],[246,52],[194,-490],[1295,408],[551,305],[581,223],[431,316],[316,3],[178,-104],[246,233],[223,88],[228,-15],[190,86]],[[22539,22676],[197,-323],[-607,-677],[-387,-333],[300,-417],[63,-166],[-425,-462],[-184,-145],[-549,-245],[-134,-190],[-252,-150],[-357,-676]],[[24649,23455],[-243,67],[-182,-189],[-169,50],[-360,-120],[-210,-147],[-390,-103],[-168,-142],[-388,-195]],[[10254,5457],[152,-331],[2,-148]],[[18744,10702],[-231,98],[-530,-172],[-191,1],[-468,-229],[-410,-450],[-410,-297],[-295,-419],[-548,-244],[-497,-342],[-305,-18],[-247,-259],[-546,-294]],[[19541,8816],[-414,1002],[-155,-75],[-109,345],[-133,-40],[-63,421],[77,233]],[[10408,4978],[1174,934],[105,-277],[204,94],[126,-332],[1562,709],[200,-644],[298,-825],[-347,-129],[103,-407],[-303,-133],[124,-378],[-185,-38],[-54,-369],[92,-276],[122,-148],[47,-736],[89,-243],[19,-420],[118,-80],[182,-436],[402,-389],[30,-417],[387,12],[401,-41],[771,217],[413,155],[67,-244],[519,622],[382,190],[505,68],[50,59],[305,-67],[267,263],[321,732],[64,211],[272,185],[293,409],[21,167],[-231,563],[-388,226],[-548,1181],[-411,821],[153,65],[-506,952],[144,63],[-124,523],[38,17],[-129,525],[1989,904]],[[9470,10251],[-289,-134],[-679,563],[-593,376],[-575,-348],[-156,-160],[-145,540],[-5,368],[-199,443],[-119,138],[-239,-141],[-70,-265],[-137,-193],[-412,-139],[-110,251],[-169,67],[-287,-159],[-205,-19],[13,-241],[-236,-112],[-378,169],[-133,-375],[214,-838],[-153,-238],[-177,-85],[107,-134],[148,-378],[315,-211],[112,-231],[215,-818],[197,-29],[290,-476],[-7,-482],[312,-698],[125,-456],[63,-582],[-89,-226],[336,-60],[8,188],[287,-27],[186,-185],[262,-58],[88,-662],[783,166],[581,198],[366,-14],[999,231],[493,203]],[[22046,9974],[-167,282],[-2,165],[153,419],[-308,-39],[-67,381],[-121,211],[-20,199],[152,168],[-16,218],[-284,-27],[-188,-163],[-44,69],[-291,-192],[-485,-186],[-477,-65],[-382,46],[-91,-246],[-208,-147],[-62,-203],[-243,-49],[-151,-113]],[[19541,8816],[2346,1069],[159,89]],[[19638,27151],[125,-597],[-184,-235],[29,-101],[-277,-110],[-145,-149],[56,-121],[217,-87],[74,-374],[-600,-382],[348,-351],[241,59],[43,-212],[252,-322],[-100,-227],[81,-71],[192,199],[2,-301],[133,-248],[217,-798],[541,241],[-30,87],[339,121],[-14,-126],[390,-90],[410,-195],[184,-165],[377,80]],[[20950,29809],[-125,-420],[50,-679],[142,-426],[-31,-415],[-265,-378],[-404,-147],[-272,39],[-407,-232]],[[24677,28513],[-215,-52],[-363,13],[-442,93],[-133,115],[-392,606],[-536,720],[-439,297],[-437,95],[-326,-110],[-231,-161],[-213,-320]],[[25297,24433],[-98,289],[-203,68],[-192,429],[-27,245],[166,334],[-65,255],[177,317],[-27,161],[115,299],[118,77],[-117,369],[-267,97],[-33,396],[54,139],[-64,296],[-114,82],[-43,227]],[[24649,23455],[291,323],[357,655]],[[20204,18892],[-141,-190],[-201,-105],[-484,-129],[-160,-208],[-752,-299],[-248,127],[-162,212],[-246,52],[-14,171],[-449,-81],[-162,365],[-609,332],[-377,-59],[-617,-233],[-957,-842],[-181,-228],[176,-1077],[-225,-442],[-432,-107],[-311,50],[-576,-208],[-567,-410],[-112,-245],[118,-368],[-348,-261],[-362,-348],[285,-205],[204,-508],[189,-343],[473,70],[172,-185],[-99,-319],[146,-91],[608,510],[138,-401],[-166,-479],[-342,19],[59,-330],[924,-377],[81,-194],[-408,-235],[-383,265],[-830,120],[-215,-235]],[[22046,9974],[901,999],[77,50],[801,260],[749,660],[593,1034],[5,793],[299,807],[474,845],[517,447],[50,100],[48,674],[317,477],[615,254],[-24,463],[-220,282],[-341,272],[-1,151],[-206,-35],[-352,1130],[-35,46]],[[25864,98657],[-622,192],[-95,288],[-270,-20],[-82,882],[-420,-83],[78,-370],[257,-871],[-384,-136],[-458,-245],[-591,-440],[190,-640],[-185,-54],[-177,111],[-214,-286],[-53,-200]],[[25207,95482],[307,1063],[80,511],[-70,479],[245,399],[80,276],[15,447]],[[22838,96785],[576,-333],[159,-309],[674,-229],[159,-18],[801,-414]],[[47737,91295],[67,-71],[-163,-312],[-162,-67],[-42,-430],[240,-241],[-475,-235],[-514,-499],[-214,-480],[-849,-693],[-211,-309],[-289,-560],[-92,-331]],[[48651,91558],[-367,97],[-547,-360]],[[50732,88403],[-724,886],[-184,145],[-133,269],[-260,263],[-188,68],[-260,381],[-61,226],[-254,304],[-44,306],[27,307]],[[49819,82772],[-17,422],[286,746],[-142,636],[-382,543],[99,475],[-27,347],[216,1245],[237,508],[586,584],[57,125]],[[45033,87067],[185,-306],[421,-269],[536,-153],[301,-43],[454,-439],[112,-247],[100,-568],[352,-674],[109,-309],[394,-357],[517,-644],[460,-15],[486,129],[151,-279],[208,-121]],[[43790,92368],[285,163],[265,24],[-23,440],[-93,108],[-222,558],[-261,530],[-65,513],[-138,390],[-90,21],[21,259]],[[41329,90742],[488,662],[437,378],[458,100],[163,-35],[313,79],[423,527],[179,-85]],[[43469,95374],[-692,301],[-516,94],[-427,-29],[-353,134],[-442,412],[-520,184],[-554,327],[-257,87],[-308,-142],[-795,176],[110,-903],[113,-399],[-66,-382],[-323,-347],[-68,-250],[99,-599],[-18,-351],[282,-80],[-151,-406],[-370,-688],[191,-96],[749,-23],[198,-181],[643,-386],[293,-28],[282,-322],[243,-200],[337,-471],[180,-64]],[[48651,91558],[144,637],[220,376],[418,342],[9,125],[-184,67],[-193,211],[-116,-136],[-216,24],[-172,301],[-498,-97],[-230,40],[-350,221],[-109,215],[12,207],[287,495],[22,109],[-192,6],[-174,450],[-165,152],[39,333],[127,220],[-32,253],[146,97]],[[43790,92368],[104,-246],[357,-253],[-38,-34],[316,-275],[313,-69],[794,154],[16,-83],[585,-239],[376,-57],[18,-117],[388,224],[55,-127],[215,80],[37,-105],[357,155],[54,-81]],[[47444,96206],[-260,547],[-189,676],[134,767],[-36,489],[-467,-187],[-335,8],[-164,-171],[-180,-19],[-695,178],[-172,-61],[-214,-290],[-293,-642],[178,1],[45,-191],[361,-121],[131,113],[260,-178],[-426,-344],[-277,-112],[391,-66],[391,-134],[-326,-241],[-574,-273],[-347,-94],[-413,193],[-328,-552],[-170,-128]],[[39906,84832],[554,-9],[1314,500],[964,391],[486,453],[294,-156],[590,100],[395,177],[187,234],[343,545]],[[41329,90742],[-266,-321],[-297,95],[-16,-637],[80,-486],[-203,-659],[-185,-723],[12,-138],[-160,-380],[-51,-317],[-178,-200],[-116,-365],[3,-795],[-174,-527],[128,-457]],[[21278,95168],[428,34],[185,-106],[505,-176],[-2,-229],[-280,-431],[5,-511],[-495,-582],[-76,-394],[-243,-235],[-80,-195],[77,-236],[215,-193],[284,-434],[356,-349],[-56,-293],[227,-564],[78,-408]],[[22838,96785],[-180,10],[-488,-211],[-267,-796],[-283,-340],[-342,-280]],[[27320,94225],[-314,57],[-519,290],[-365,62],[-208,202],[-274,114],[-415,407],[-18,125]],[[22406,89866],[454,91],[697,-130],[318,-96],[663,-11],[184,63],[478,328],[440,160],[1500,4],[410,37],[-175,976],[-227,1454],[-68,539],[240,944]],[[18893,94868],[-354,-308],[-255,-324],[-195,-346],[-771,-834],[-166,-223],[-415,-308]],[[21278,95168],[-509,-157],[-406,-58],[-558,-239],[-185,7],[-327,124],[-220,-59],[-180,82]],[[16737,92525],[-280,-132],[-532,-611],[-321,-715],[-301,-305],[-99,-180],[80,-95],[50,-700],[153,-471],[911,-1312],[193,-492],[246,6],[900,538],[550,291],[230,258],[400,133],[859,221],[527,16],[581,402],[318,160],[813,252],[391,77]],[[50732,88403],[121,283],[308,180],[229,20],[133,108],[236,13],[93,134],[47,342],[-86,477],[193,415],[17,205],[335,342],[128,286],[335,505],[87,316],[326,290],[195,-27],[-286,749],[-408,823],[-390,409],[-385,638],[-513,267],[-750,-45],[-1012,302],[-1017,494],[-759,-123],[-465,400]],[[18893,94868],[-283,523],[-392,415],[-273,639],[-49,-26],[-213,390],[-168,-68],[-78,119],[-227,-122],[-390,-58],[-191,229],[-614,194],[-295,318],[51,41],[-297,362],[-865,398],[-206,238],[-396,222],[-280,239],[-266,-218],[-241,-360],[-249,-478],[-109,-584],[-291,-320],[-177,-291],[-182,-544],[-314,-517],[-117,-629],[-100,-199],[180,106],[534,109],[192,100],[332,286],[395,-451],[67,84],[263,-196],[261,29],[371,-327],[407,-270],[134,171],[156,-73],[118,-217],[276,-269],[25,-268],[273,-350],[255,360],[179,-46],[420,-316],[205,-94],[87,-147],[-74,-477]],[[39906,84832],[-47,-1136]],[[42317,78399],[1007,1],[2582,-214],[573,165],[368,58],[1413,1181],[859,576],[459,1787],[241,819]],[[37581,79727],[255,-233],[172,-306],[384,-193],[1338,423],[1315,-166],[561,-478],[711,-375]],[[39859,83696],[232,-954],[23,-570],[-531,-513],[-307,-193],[-499,-672],[-672,-416],[-524,-651]],[[27320,94225],[173,87],[405,-7],[164,562],[288,734],[63,283],[-105,44],[50,795],[-14,562],[-524,-20],[-12,1043],[-107,458],[-780,-59],[-754,-91],[-303,41]],[[73142,66653],[469,87]],[[71411,68585],[109,-540],[-14,-180],[220,-129],[136,-216],[430,-195],[35,-204],[478,9],[-53,-501],[390,24]],[[77931,72365],[-394,222],[-823,-527],[-263,-226],[-145,61],[-653,100],[-464,-201],[22,-212],[-182,-113],[-1265,-333],[-144,-238],[-233,-144],[-619,-206],[-425,-258],[-92,-144],[-369,-337],[-59,-322],[-226,-335],[-186,-567]],[[78140,72350],[-209,15]],[[75710,66855],[-19,694],[89,309],[443,647],[350,383],[-22,263],[-375,107],[-194,262],[-305,9],[-203,202],[-380,-106],[-108,-171],[-246,99],[93,243],[-224,184],[453,189],[564,-28],[805,-322],[510,-101],[168,293],[136,-134],[217,282],[309,144],[80,836],[305,410],[-16,801]],[[73611,66740],[352,173],[580,6],[536,-93],[315,54],[316,-25]],[[89886,81392],[197,123]],[[90083,81515],[622,270],[479,286],[466,229],[473,159],[401,287],[370,185],[164,-4],[65,-1264],[178,-29],[252,1398],[-93,132],[63,132],[-243,440],[120,229],[-177,349],[-202,745],[66,672],[-62,680],[-179,345],[-63,288],[-223,689],[-266,196],[-566,519],[78,240],[161,190],[-90,650],[-246,681],[-156,70],[-649,539],[-29,145],[-199,-115],[-223,-468],[-202,-182],[-185,20],[-342,-465],[43,-497],[-207,-173],[-151,123],[-301,-95],[245,-116],[87,-361],[-226,-196],[133,-177],[-129,13],[-186,-148],[-199,-386],[-201,-70],[-102,-207],[-237,-231],[-61,-271],[-369,-47],[-104,-552],[190,-740],[570,-1685],[-274,-251],[826,-1195],[725,-806],[168,-293]],[[90776,69815],[227,718],[114,476],[204,263]],[[86668,69471],[589,798],[489,-517],[709,-207],[-1,370],[473,-120],[-3,545],[226,29],[174,-179],[349,63],[383,-83],[348,-217],[372,-138]],[[80433,72094],[1102,-37],[800,-812],[259,-32],[526,174],[320,-17],[522,-154],[276,-154],[288,347],[464,65],[150,-23],[-40,-413],[402,-640],[503,-604],[130,132],[270,64],[84,-111],[-102,-115],[281,-293]],[[80048,72605],[126,-308],[259,-203]],[[82380,75900],[-144,-198],[-232,-635],[-133,-630],[-290,-933],[-534,-328],[-101,-103],[-424,-175],[-474,-293]],[[86275,78150],[-584,-654],[-399,-168],[-305,-226],[-338,-149],[-176,-222],[-456,75],[-167,-102],[-981,-401],[-307,-199],[-182,-204]],[[91321,71272],[-588,230],[-98,-41],[-92,334],[-163,122],[-476,782],[-472,985],[-53,168],[-30,565],[-301,-250],[-75,423],[-127,216],[-119,-28],[-56,278],[-126,38],[-37,592],[130,284],[-269,555],[214,81],[160,413],[23,207],[-200,108],[-300,528],[-229,177],[-761,119],[-799,16],[-202,-24]],[[95585,71535],[-560,311],[-836,255],[-271,153],[-436,457],[-134,684]],[[94661,68375],[98,585],[96,316],[482,899],[123,345],[125,1015]],[[91325,68703],[920,-342],[61,-459],[163,-128],[627,-119],[-218,286],[40,82],[685,-404],[503,-22],[377,142],[149,281],[29,355]],[[90449,68632],[687,130],[189,-59]],[[90776,69815],[-210,-302],[15,-142],[-128,-147],[67,-211],[-71,-381]],[[93348,73395],[-424,-602],[-449,-472],[-218,-399],[-936,-650]],[[86668,69471],[-162,-220],[420,-443],[133,-224],[-68,-82],[172,-247],[-96,-37],[23,-336],[-133,-733],[-52,-548]],[[89543,65099],[498,172],[242,438],[277,305],[53,436],[-298,940],[-88,378],[82,632],[140,232]],[[86905,66601],[291,131],[628,-226],[341,-166],[306,-242],[282,-601],[363,-277],[427,-121]],[[89153,80686],[-355,-362],[252,-144],[-137,-249],[-141,83],[-446,103],[-376,-39],[-284,-173],[-115,13],[-86,-250],[-296,-14],[-338,-90],[-529,-282],[-292,-268],[126,-268],[139,-596]],[[93348,73395],[-46,912],[-66,416],[-39,790],[-134,570],[365,128],[-40,191],[-290,-68],[4,203],[-114,362],[-236,-51],[-155,397],[-595,445],[-131,334],[-1066,946],[-167,537],[-316,558],[-344,381],[-436,-72],[-389,312]],[[80048,72605],[-298,-149],[-812,302],[-798,-408]],[[83713,68987],[-169,337],[-2,275],[-187,143],[-92,-124],[-998,183],[-408,22],[-321,-195],[-226,-22],[69,476],[135,323],[184,223],[-254,318],[237,343],[-275,339],[-973,466]],[[77679,66589],[524,440],[481,299],[470,-55],[88,59],[634,-193],[390,-194],[84,-152],[196,82],[355,-134],[19,-221],[182,-444],[366,25],[524,-52],[118,588],[141,383],[511,891],[606,829],[345,247]],[[75710,66855],[250,24],[421,131],[217,120],[459,-502],[55,-173],[190,99],[377,35]],[[85236,66362],[129,-93],[253,13],[551,171],[736,148]],[[83713,68987],[236,-144],[171,-399],[297,-1137],[212,-349],[607,-596]],[[82380,75900],[-452,303],[-185,230],[-216,379],[-279,-101],[-154,-303],[-282,215],[-665,644],[-595,624],[-239,28],[-484,-225],[-272,-53],[114,-285],[-93,-245],[120,-148],[-150,-225],[31,-238],[-235,-115],[-292,231],[-303,-109],[-346,-857],[-473,-189],[-413,-303],[411,-993],[284,-283],[318,84],[141,-82],[40,-228],[304,-244],[45,-149],[-125,-318],[112,-352],[-116,-228]],[[89886,81392],[-492,-304],[-303,-269],[62,-133]],[[99412,74785],[-127,560],[-902,36],[-49,-425],[-385,200],[-169,34],[-371,-148],[-434,158],[-114,143],[46,603],[-18,677],[-136,132],[-154,546],[-122,581],[-278,129],[-242,334],[-249,186],[-762,181],[-391,204],[-360,20],[-173,205],[-129,487],[-253,-190],[-424,172],[-417,-115],[-287,225],[-83,155],[-304,187],[-445,790],[-280,-124],[-426,292],[-891,495]],[[97934,72409],[303,38],[114,157],[279,715],[289,1162],[223,231],[270,73]],[[95585,71535],[-16,182],[132,408],[148,301],[420,555],[423,189],[336,-106],[139,-158],[498,-391],[269,-106]],[[44369,22779],[76,-110],[86,-592],[160,-199],[205,-86],[-214,-254],[293,-670],[189,-211],[207,-55]],[[46198,26232],[-505,-427],[-18,-334],[-102,-450],[-376,-239],[-342,-342],[26,-337],[281,-568],[-96,-125],[39,-170],[-215,-201],[-521,-260]],[[48008,25773],[-823,5],[-273,92],[-19,84],[-496,187],[-50,-144],[-149,235]],[[45371,20602],[212,202],[834,1202],[136,-174],[620,291],[106,-122],[995,9],[129,1404],[290,282],[102,284],[157,1254],[31,113],[-425,108],[114,131],[-347,149],[-130,-233],[-187,271]],[[52336,20478],[-927,50],[-3,135],[-326,378],[-177,140],[-443,102],[151,252],[-64,93],[-456,-102],[-120,-150],[76,-132],[-262,-185],[-200,-238],[-5,-252],[-333,219],[-210,-374],[-40,-340],[-184,-464],[-223,-390],[156,-93],[-31,-189],[-205,-295],[123,-170],[701,256],[366,-41],[826,-308],[270,-59],[191,447],[216,625],[122,238],[267,-152],[531,774],[129,39],[84,186]],[[34467,27773],[-351,432],[-163,-161],[-63,-192],[-391,-7],[-43,680],[-116,-112],[-77,175],[-221,140],[-32,194],[-226,99],[-241,13],[-490,223],[-35,-151],[-393,268],[-27,-387],[-547,-525],[-57,47],[-437,-194],[-266,172],[-195,231],[-50,436],[327,75],[-374,290],[-314,302]],[[34465,24089],[-427,1013],[277,387],[201,134],[-368,842],[367,269],[-115,302],[102,101],[-35,636]],[[31721,21898],[462,1761],[355,-111],[136,-143],[476,-89],[254,137],[525,108],[238,132],[50,207],[248,189]],[[28827,20759],[248,95],[149,-296],[384,-467],[288,86],[365,325],[175,351],[860,585],[212,247],[59,198],[154,15]],[[25297,24433],[286,246],[538,199],[291,-195],[-34,268],[85,409],[-310,-58],[-157,110],[-32,236],[184,353],[41,436],[335,214],[218,-268],[422,58],[156,-161],[-126,-168],[-60,-320],[41,-659],[235,-113],[156,422],[367,-33],[43,-110],[404,-327],[203,-248],[135,-301],[312,283],[205,-288],[-226,-145],[188,-349],[-82,-53],[221,-411],[-145,-70],[144,-163],[-148,-198],[-366,-313],[212,-156],[356,-32],[98,-302],[270,-339],[-432,-369],[-375,-260],[-330,-137],[207,-362]],[[25121,28480],[-444,33]],[[29685,29821],[-208,-136],[-287,-421],[93,-87],[-123,-115],[-336,-67],[-99,-143],[-289,347],[-41,-394],[-784,598],[-262,-340],[-343,-260],[-776,-364],[-372,-48],[-737,89]],[[44330,29459],[402,-419],[488,-286],[382,-666],[114,7],[181,-424],[-120,-143],[127,-181],[-298,-260],[249,-308],[343,-547]],[[44531,29792],[-201,-333]],[[48008,25773],[74,515],[301,277],[133,699],[-486,488],[66,312],[-33,149],[-347,-205],[-89,438],[-270,-21],[-125,499],[-236,-125],[-211,270],[-61,537],[-654,-64],[-381,114],[-1158,136]],[[35833,35798],[182,-707],[183,-31],[862,318],[268,-20],[512,-139],[175,-473],[-109,-571],[37,-343],[361,-29],[-309,-752],[-173,-622]],[[36847,36232],[-199,-150],[-435,-208],[-380,-76]],[[40678,36118],[-763,-1090],[-239,213],[-356,-186],[-217,541],[99,7],[-243,302],[-378,228],[-307,89],[-397,46],[-932,-94],[-98,58]],[[44729,31937],[-207,594],[-168,278],[-8,294],[93,375],[263,322],[-134,120],[-297,-15],[-116,243],[-531,158],[-273,525],[691,483],[-494,1014],[-764,-600],[-196,327],[-441,-455],[-200,367],[-483,-457],[-388,710],[-398,-102]],[[37643,30790],[638,124],[113,-383],[819,228],[23,-113],[733,223],[34,-151],[480,71],[78,-247],[579,816],[322,366],[139,328],[250,-126],[239,12],[37,-331],[232,-43],[959,148],[681,-52],[730,277]],[[37822,32429],[-90,-588],[-87,-796],[-2,-255]],[[38456,27588],[45,85],[-472,302],[267,492],[-636,408],[-17,1915]],[[37599,25154],[55,203],[332,675],[-204,448],[357,348],[247,754],[70,6]],[[35713,23410],[269,-92],[156,246],[146,102],[206,613],[71,-29],[364,983],[151,-193],[151,97],[372,17]],[[34465,24089],[49,76],[301,-175],[166,-226],[546,-35],[186,-319]],[[34642,29441],[76,-137],[-20,-247],[84,-333],[-42,-521],[-273,-430]],[[37822,32429],[-126,-42],[-624,-458],[-7,-255],[-347,4],[72,-320],[18,-515],[-271,-97],[6,-296],[-1073,-13],[35,-113],[-342,16],[42,72],[-351,16],[-110,-765],[63,-118],[-165,-104]],[[44330,29459],[-293,-255],[-486,-92],[-583,-351],[-54,-120],[-525,-797],[180,-146],[-321,-435],[167,-161],[-161,-27],[39,-215]],[[43361,23902],[342,-346],[457,-313],[209,-464]],[[42293,26860],[311,84],[296,-303],[186,-279],[355,257],[187,-129],[-187,-130],[99,-176],[147,99],[139,-173],[-249,-146],[312,-377],[-195,-201],[84,-151],[70,-530],[-72,-314],[-309,-268],[-106,-221]],[[35757,23280],[-44,130]],[[34048,21052],[487,233],[-291,322],[391,276],[199,213],[-138,311],[162,102],[-204,377],[195,173],[147,-340],[137,71],[75,-204],[158,-101],[-6,291],[75,380],[322,124]],[[31721,21898],[664,63],[163,-483],[-29,-124],[229,-51],[-64,-276],[262,-271],[281,-167],[58,98],[763,365]],[[37259,21921],[129,-85],[55,-356],[684,150],[162,-347],[220,-280],[209,194],[392,-521],[279,316],[574,-495]],[[37949,23394],[-187,-416],[-373,34],[85,-441],[-215,-650]],[[41373,22155],[-283,-120],[-392,0],[176,125],[79,345],[-241,35],[72,347],[-530,139],[-94,-408],[-881,211],[-55,-146],[-164,16],[82,375],[-795,82],[-398,238]],[[39963,20497],[82,392],[255,172],[490,-114],[444,-45],[-30,-282],[75,-122],[287,175],[-178,144],[230,214],[16,255],[-184,130],[22,93],[258,52],[-357,594]],[[42137,26841],[-1455,266],[-149,-78],[114,-225],[-263,-80],[22,-185],[-362,35],[-324,-301],[-140,24]],[[43361,23902],[-229,310],[-708,208],[-77,70],[-81,463],[-165,456],[-335,-254],[-168,238],[421,408],[-235,376],[377,489],[-24,175]],[[43096,22565],[602,143],[439,15],[232,56]],[[39580,26297],[-316,-218],[213,-427],[-120,-205],[142,-292],[-148,-122],[172,-232],[-108,-63],[164,-360],[-76,-79],[589,-288],[492,-113],[-3,-202],[189,-137],[467,-217],[543,-39],[605,-282],[360,-60],[351,-396]],[[42293,26860],[-156,-19]],[[37949,23394],[156,225],[-135,76],[59,307],[-255,21],[31,455],[-56,94],[57,503],[-207,79]],[[35733,22396],[409,-4],[-7,-67],[428,-378],[186,236],[192,-199],[318,-63]],[[35757,23280],[67,-127],[-91,-757]],[[26480,20168],[470,81],[-40,268],[817,186],[186,172],[266,103],[106,-399],[542,180]],[[33421,33814],[986,-3194],[39,-247],[-21,-452],[217,-480]],[[35833,35798],[-159,-25],[-567,-234],[-625,-329],[-266,-184],[-648,-954],[-147,-258]],[[36244,18058],[-236,590],[216,94],[244,242],[-96,514],[-296,46],[-152,464],[259,124],[-99,714],[-393,141],[165,456],[-360,76],[-181,425],[400,-7],[18,459]],[[34048,21052],[375,-623],[318,-408],[153,78],[199,-484],[-142,-628],[252,87],[82,-276],[401,-1689],[320,781],[238,168]],[[39580,26297],[-555,661],[-19,92],[-550,538]],[[41373,22155],[-178,212],[223,306],[511,-306],[173,-207],[173,292],[418,204],[148,-124],[255,33]],[[40483,18737],[328,359],[443,194],[-261,258],[-204,113],[-181,322],[-430,283],[-244,79],[29,152]],[[36244,18058],[355,251],[793,-248],[925,243],[521,50],[438,206],[533,190],[5,209],[138,268],[531,-490]],[[44531,29792],[320,542],[258,608],[-236,762],[-144,233]],[[30750,32120],[-318,-911],[-240,-240],[-223,-27],[1,-854],[-24,-185],[-261,-82]],[[32380,33379],[-196,33],[-632,-66],[-360,-170],[-149,-197],[-293,-859]],[[33421,33814],[-320,-349],[-212,-106],[-509,20]],[[40483,18737],[404,-328],[53,81],[329,-221],[426,116],[228,-131],[337,340],[135,-197],[245,122],[118,-47],[112,-283],[632,343],[121,-204],[0,-277],[368,-299],[-18,-86],[280,-215],[276,149],[517,59],[135,103],[214,510],[-84,19],[-66,823],[-151,16],[-26,292],[75,29],[329,771],[-255,192],[154,188]],[[32135,42205],[-208,86],[-50,328],[-421,272],[-118,148],[320,246],[-86,132],[30,330],[-313,8],[-100,181],[-135,-28],[-580,175],[-349,888],[133,119],[421,108],[446,-34],[436,-382],[1063,227],[17,395],[-207,616],[662,294],[-1,78]],[[31115,40171],[83,-68],[392,123],[-45,192],[67,204],[421,453],[186,95],[209,233],[487,169],[157,105],[-178,83],[-192,281],[15,121],[-463,-51],[-119,94]],[[25862,43379],[244,-274],[62,-282],[-243,-377],[44,-167],[439,233],[415,141],[368,308],[317,-397],[295,-191],[570,59],[663,-52],[51,-369],[139,-77],[931,-707],[131,-216],[183,-141],[204,84],[242,-365],[29,-303],[169,-115]],[[25121,28480],[-326,524],[-285,2382],[15,54],[626,238],[263,224],[133,332]],[[19656,32918],[190,-616],[56,-287],[-223,-71],[38,-143],[171,53],[109,-474],[-165,-55],[101,-478],[60,6],[225,-676],[253,-189],[479,-179]],[[21454,34964],[-148,-228],[-190,67],[65,-348],[-129,13],[82,-181],[298,-184],[110,-277],[13,-268],[-474,18],[-254,-91],[-80,-170],[-252,-100],[-314,-43],[-293,-184],[-232,-70]],[[23391,34077],[-562,670],[-503,111],[-136,97],[-736,9]],[[25547,32234],[-431,25],[-297,275],[-252,357],[-368,198],[-374,-5],[-154,449],[111,242],[-231,241],[-160,61]],[[10002,36877],[-388,-256],[-449,-181],[-1079,-380],[-205,-94],[-243,-575],[134,-129],[-666,-548],[-19,-282],[79,-343],[215,-609],[531,-920],[343,-292],[278,-502],[412,-615],[312,-271],[107,25],[46,-243],[255,-529],[270,-361],[148,-299],[-4,-201],[166,83],[545,-1402],[323,18],[230,-711],[222,-324],[146,-697],[208,-498],[197,-280],[114,-488],[264,23],[137,-113],[255,-26],[245,84]],[[15865,25866],[-467,-25],[-4,-59],[-401,-192],[-176,800],[-230,-95],[-212,517],[-249,-107],[-339,851],[482,153],[-335,815],[-204,586],[315,124],[-92,354],[241,46],[-25,186],[-117,-34],[-61,265],[39,534],[-53,284],[-251,86],[-204,567],[-206,380],[215,18],[-57,379],[408,391],[495,157],[-49,386],[-282,338],[-97,342],[-344,417],[-21,109],[-273,217],[-223,-27],[-319,176],[-271,-28],[-192,86],[-210,516],[-180,212],[-696,476],[-120,-237],[-614,46],[-217,311],[-46,231],[-221,459]],[[13131,24941],[1,295],[114,265],[230,266],[399,132],[203,-60],[153,-160],[209,-867],[103,-198],[173,-130],[207,4],[339,187],[297,242],[281,420],[54,256],[-29,273]],[[29452,34001],[265,25],[474,-627],[41,-178],[157,-49],[-61,-240],[135,-117],[-50,-337],[111,-321],[226,-37]],[[30429,38447],[-157,-197],[-815,-201],[85,-1371],[268,-596],[-174,-1030],[-227,-848],[43,-203]],[[32380,33379],[-2,182],[178,150],[10,234],[-243,466],[188,257],[-170,175],[-392,-313],[-285,135],[397,485],[-150,772],[-5,231],[-496,51],[-148,119],[-493,-294],[2,303],[266,494],[-108,-29],[-164,145],[-182,372],[198,63],[-352,1070]],[[40678,36118],[-241,28],[-116,553],[-277,342],[91,228],[-313,80],[-135,534],[-441,408],[-242,-10],[35,311],[-453,-116],[-145,182],[11,470],[-128,193],[-316,-138],[-529,727],[-147,38],[-51,-128]],[[35548,38348],[124,-250],[35,-272],[-276,-161],[484,-1408],[144,67],[590,63],[198,-155]],[[37281,39820],[128,-492],[-75,-248],[-212,28],[-170,242],[-433,-543],[-297,-299],[-228,-95],[-446,-65]],[[10002,36877],[466,414],[288,187],[-270,822],[-122,500]],[[10364,38800],[-563,-333],[-160,-222],[-747,-766],[-523,-329],[-366,-181],[-423,-151],[-200,-142],[-550,-166],[-367,-210],[-675,-242],[-307,-270],[-536,-184],[-577,-689],[-479,-368],[-262,-348],[-147,-44],[-315,-240],[-423,-2],[-235,136],[-67,203],[-352,-40],[-217,-144],[-619,-191],[-395,-63],[-454,-287],[-405,-83],[224,-1208],[413,-1211],[292,1],[1106,-3663],[493,158],[725,287],[377,235],[247,-689],[149,-172],[431,-134],[577,-380],[306,-320],[331,-491],[578,-1120],[183,-543],[248,-588],[464,-1185],[322,-959],[-157,-17],[1,-146],[-895,124],[-363,-230],[-59,-346],[135,-585],[140,-182],[474,-195],[56,141],[692,229],[153,-175],[569,361],[565,221],[303,-5],[805,-172],[472,76],[236,175],[365,515],[82,442],[24,419],[100,276],[150,211],[496,267],[616,158],[287,131],[297,244],[219,343],[31,623],[-129,576]],[[34775,40885],[114,-43],[884,61],[397,410]],[[32135,42205],[305,37],[247,167],[519,197],[25,-351],[168,-139],[455,-154],[83,-194],[321,-6],[-31,-364],[293,210],[-41,112],[77,295],[253,-914],[-34,-216]],[[36910,44238],[-175,576],[-984,810],[-991,1550]],[[36170,41313],[-152,534],[-127,118],[-147,372],[43,955],[-67,393],[1190,553]],[[37221,41190],[-268,-24],[-266,80],[-128,-279],[-304,42],[-85,304]],[[37281,39820],[-213,174],[153,1196]],[[34775,40885],[-64,24],[135,-878],[-138,-327],[37,-336],[202,17],[120,-410],[210,-106],[-1,-403],[272,-118]],[[37221,41190],[102,804],[-233,1543],[-180,701]],[[26874,36522],[-962,-471],[-987,-593],[12,-225],[-550,-131],[-96,-298],[-265,-117],[-635,-610]],[[26805,33810],[8,218],[-138,422],[66,120],[-46,332],[220,372],[13,156],[318,223],[-117,73],[-222,447],[-33,349]],[[25547,32234],[46,354],[-239,244],[-23,202],[62,435],[-55,119],[243,28],[699,-118],[71,-139],[118,184],[336,267]],[[18105,39493],[-349,-171],[-467,-100],[-22,-69],[-518,-105],[-563,-232],[-197,-126],[707,-3558],[355,-753],[-120,-115],[126,-508],[58,-424],[471,142],[345,-89],[102,-170],[55,-307],[158,13],[159,-159],[340,-110],[259,36],[652,230]],[[21454,34964],[-182,185],[-150,-5],[-36,151],[-282,-64],[-7,223],[-427,-56],[74,206],[-106,184],[-132,-18],[-33,243],[249,41],[-75,183],[-111,-17],[-172,272],[83,29],[-307,258],[-103,409],[-96,-69],[-489,1809],[-143,608],[-904,-43]],[[16332,41372],[89,-338],[164,-100],[372,-366],[294,11],[-30,-316],[64,-307],[109,-77],[285,150],[279,36],[123,-288],[24,-284]],[[26874,36522],[-14,296],[-125,439],[-475,391],[-263,447],[-118,481],[-152,220],[-21,193],[-207,67],[-229,624],[98,146],[-162,642],[-260,1291],[558,1033]],[[31115,40171],[-41,-343],[260,-372],[115,-778],[-390,-88],[-333,-134],[-297,-9]],[[26805,33810],[559,-28],[67,173],[204,-2],[270,-107],[70,-192],[265,60],[225,-43],[390,223],[276,32],[161,135],[160,-60]],[[11677,39345],[-782,-626],[-190,79],[-341,2]],[[15865,25866],[-192,637],[58,353],[138,41],[197,-121],[671,-51],[553,54],[1018,245],[395,53],[714,20],[221,54]],[[72495,51547],[573,-584],[735,-832]],[[73984,55726],[-221,-151],[6,-199],[-239,-292],[-306,-262],[-65,-181],[-69,-620],[113,-1380],[-18,-1231],[-690,137]],[[78242,55984],[-953,-68],[24,-94],[-283,-68],[-980,-323],[-402,45],[-199,-98],[-67,230],[150,-25],[-2,215],[-169,136],[-692,144],[4,-53],[-689,-299]],[[78296,55562],[-54,422]],[[73803,50131],[290,368],[302,663],[119,583],[141,398],[403,848],[169,786],[123,354],[181,236],[292,250],[519,220],[304,212],[550,520],[521,83],[579,-90]],[[93338,61973],[670,103],[334,472],[-32,738],[-141,488],[29,500],[-263,535],[20,529],[109,160],[-284,427],[-44,170],[-340,488],[-102,-24],[-250,319],[-349,90],[-127,-34],[-183,324],[-195,231],[-200,-275],[29,-230],[-666,24],[-234,471],[-274,805],[247,-22],[835,-355],[-168,179],[-434,617]],[[90417,61741],[676,-845],[149,46],[499,13],[263,1158],[129,24],[418,-311],[50,-144],[347,199],[390,92]],[[89543,65099],[189,-372],[389,-456],[244,-589],[-166,-676],[-27,-747],[87,-11],[-9,-254],[167,-253]],[[87985,60527],[78,93],[224,-175],[355,-175],[421,152],[83,307],[232,-160],[131,138],[-61,458],[362,-48],[98,194],[-7,204],[386,116],[130,110]],[[85581,60633],[939,-124],[1362,-25],[103,43]],[[85103,66189],[208,-502],[66,-340],[436,-545],[205,-341],[-256,-580],[1,-405],[-89,-343],[-273,-653],[255,-315],[162,-644],[242,-649],[-479,-239]],[[85236,66362],[-133,-173]],[[99126,68832],[223,224],[87,350],[-34,113],[79,453],[94,139],[-86,246],[199,317],[99,497],[-45,373],[187,475],[-8,246],[78,300],[-230,642],[-357,1578]],[[97934,72409],[344,-355],[-404,-422],[303,-515],[49,-587],[323,-805],[162,35],[-376,-722],[73,-164],[336,-115],[382,73]],[[70723,44992],[246,74],[483,267],[1244,1547],[256,493],[80,311],[29,595],[59,364],[256,422],[191,418],[52,307],[184,341]],[[93338,61973],[448,-299],[175,-283],[43,-288],[203,-221],[151,-287]],[[98263,67863],[-533,114],[-733,-825],[-182,264],[-220,434],[-157,520],[-501,150],[-167,-266],[-596,-441],[126,469],[-639,93]],[[94358,60595],[643,199],[607,329],[83,-17],[257,285],[336,187],[310,598],[-454,963],[-65,436],[1149,1060],[111,500],[27,555],[-344,609],[348,282],[189,316],[363,263],[-29,136],[123,304],[251,263]],[[71232,59278],[-299,-73],[-1762,-744]],[[73984,55726],[-94,116],[-119,425],[-383,-216],[-186,161],[-312,403],[-363,291],[149,180],[-325,291],[-205,422],[-154,-40],[-185,263],[-437,905],[-103,118],[-35,233]],[[71411,68585],[-147,-254],[-296,-299],[-718,-251],[-272,-25],[-236,-137],[-355,-94],[-1057,-73],[-258,43],[-185,-118],[-558,-3],[-464,-304],[-647,-1241],[-185,-543],[-193,-865],[56,-773],[-264,-1604]],[[74881,60337],[-254,531],[-322,889],[-223,249],[-85,-61],[-90,175],[-421,336],[-236,264],[207,183],[-156,657],[-279,183],[-534,40],[-130,449],[70,290],[298,243],[286,300],[156,509],[100,88],[-126,991]],[[71232,59278],[353,61],[301,-118],[448,238],[353,-383],[907,366],[281,164],[508,494],[498,237]],[[77007,58378],[-420,750],[-267,315],[-150,82],[-400,528],[63,46],[-298,346],[-235,200],[-166,-189],[-253,-119]],[[78231,57154],[-424,-102],[-128,394],[-451,630],[-251,203],[30,99]],[[78242,55984],[61,571],[-72,599]],[[83346,61455],[385,204],[395,-42],[269,199],[160,302],[-251,238],[-132,516],[281,1390],[30,442],[-18,547],[96,216],[542,722]],[[78296,55562],[446,-113],[702,60],[166,249],[124,563],[151,236],[266,259],[238,318],[418,420],[-230,448],[-75,469],[107,872],[294,668],[465,927],[339,578],[401,456],[137,321],[-67,343],[198,-14],[25,-162],[272,-412],[673,-593]],[[77679,66589],[-3,-169],[-277,-430],[49,-269],[327,-400],[193,-345],[548,-812],[199,-449],[451,-725],[-208,-115],[-396,-317],[-583,-346],[314,-641],[377,-540],[321,-625],[27,-307],[171,-437],[61,-353],[161,-118],[-126,-691],[78,-250],[152,-40],[-63,-486],[-559,-446],[-264,29],[-398,-153]],[[77007,58378],[197,415],[-174,496],[20,211],[-108,341],[-665,1081],[-187,399],[-224,268],[-455,852],[-226,784],[-984,2030],[-590,1485]],[[98263,67863],[696,384],[167,585]],[[83346,61455],[343,-304],[150,-318],[1742,-200]],[[87985,60527],[147,-686],[-109,-667],[-103,-362],[-29,-683],[70,-547],[116,-419],[-50,-225],[900,479],[638,263],[704,210],[1010,259],[-15,69],[886,221],[-63,287],[288,204],[-38,104],[973,592],[113,-214],[299,258],[-15,212],[295,275],[226,485],[130,-47]],[[22330,69171],[284,985],[117,845],[-328,690],[-196,-69],[-711,250],[203,332],[107,460]],[[21806,72664],[-363,144],[-497,279],[-23,342],[-187,70],[-330,-95],[-150,190],[-149,32],[-105,183],[-131,424],[-2,626],[-98,233],[104,560],[-19,650],[-565,-205],[-384,30],[-893,489],[-166,-105],[-53,-218],[-120,-90],[-765,169],[-94,393],[-211,223],[-671,-79],[-91,-68],[16,-232],[137,-171],[17,-203],[-140,-247],[-196,-77],[-190,27],[-306,219],[-118,338],[-112,66],[-310,-500],[98,-133],[-95,-332],[99,-252],[161,-173],[-105,-359],[76,-368],[53,-525],[-48,-145],[93,-330],[-223,-120],[-438,-570],[4,-225],[-176,-420],[14,-348],[-90,-203],[-173,-649],[585,506],[496,-375],[199,-82],[262,-400],[250,-175],[625,-299],[288,-550],[290,-169],[698,-231],[396,-48],[271,56],[177,-97],[509,32],[208,90],[265,-3],[402,130],[343,51],[299,-144],[859,-256],[1017,226]],[[33276,69393],[-451,11],[-488,85],[-25,-503],[-210,-751],[98,-341],[134,-82],[-431,-172],[-175,140],[-26,200],[-344,44],[-133,-267],[-9,-177],[-212,-647],[73,-186],[-126,-55],[22,-159],[-637,-234],[-325,61],[-314,347],[-267,75],[-557,-64]],[[39781,68677],[-113,-313],[-205,-68],[-182,42],[-109,210],[-316,364],[-369,-220],[-228,-237],[-160,11],[-514,291],[-802,388],[-401,269],[-625,-309],[-616,-118],[-241,268],[-273,127],[-324,-7],[-302,89],[-166,271],[-326,-176],[-63,-199],[-170,33]],[[43537,70991],[-590,-63],[-644,57],[-542,185],[-291,-282],[220,-301],[-211,-215],[-329,-192],[-153,-384],[-1034,-1032],[-182,-87]],[[44001,68407],[-196,1425],[43,503],[-163,300],[-18,239],[-130,117]],[[28873,66718],[176,-813],[86,-208],[-291,-593],[-209,-240],[-162,-463],[183,-213],[135,-402],[232,-40],[172,93],[448,-78],[327,-200],[162,-34],[445,-249],[117,-13],[620,-338],[24,-413],[457,135],[276,-278],[190,-372],[-42,-100],[684,-1273],[540,-867],[111,-216]],[[34799,79472],[-569,-131],[-1551,-175],[-986,107],[-426,88],[-746,21],[-1167,-76],[-1205,-171],[-1374,-392],[265,-377],[36,-352],[208,-213],[355,-627],[-3,-323],[-74,-264],[-259,-329]],[[35390,78695],[-150,49],[-441,728]],[[35581,76909],[224,452],[-39,278],[-229,253],[60,305],[-159,141],[-48,357]],[[33147,74769],[226,116],[111,462],[-102,238],[112,511],[291,161],[286,6],[471,128],[256,245],[341,605],[442,-332]],[[27303,76258],[141,-51],[1801,-164],[1389,-314],[730,-128],[702,-312],[664,-242],[114,26],[179,-266],[124,-38]],[[33148,72514],[498,145],[465,277],[81,440],[222,601]],[[26219,71411],[531,175],[431,-137],[542,-52],[351,-120],[111,-191],[266,199],[60,168],[225,-88],[239,34],[194,-161],[348,132],[72,128],[393,132],[223,188],[88,-38],[375,87],[199,-19],[459,113],[386,-28],[193,-98],[619,174],[-54,158],[427,185],[251,162]],[[25622,73343],[19,-204],[5,-1119],[343,-292],[230,-317]],[[27303,76258],[-371,-605],[-712,-1680],[-397,-696],[-201,66]],[[34414,73977],[-305,-188],[-83,264],[-363,295],[-329,140],[-187,281]],[[25875,69515],[224,-35],[467,27],[90,-105],[42,-423],[-422,-838],[5,-251],[218,-208],[649,-353],[377,45],[199,-135],[218,-33],[-66,-205],[154,-391],[252,57],[591,51]],[[26219,71411],[-1,-709],[-203,-329],[-320,-92],[180,-766]],[[33276,69393],[75,428],[-187,146],[29,160],[-157,432],[169,42],[139,695],[-196,1218]],[[35580,76905],[1,4]],[[36165,74914],[-147,66],[29,224],[-95,210],[69,89],[-79,328],[-365,774],[3,300]],[[34414,73977],[1147,399],[604,538]],[[22330,69171],[556,250],[351,71],[196,-24],[1204,75],[592,-14],[398,30],[248,-44]],[[25622,73343],[-858,287],[-1192,-1104],[-324,-100],[-444,-14],[-998,252]],[[35390,78695],[423,47],[53,464],[164,216],[496,226],[431,17],[284,79],[340,-17]],[[39859,83696],[-257,141],[-380,-133],[-573,-31],[-761,-332],[-519,204],[-660,55],[-279,79],[-1034,-956],[-535,35],[-276,328],[115,435],[-354,90],[95,315],[16,262],[-159,117],[-248,312],[-347,-80],[-626,114],[-46,-95],[89,-322],[-61,-683],[56,-163],[-32,-500],[-102,-550],[-105,-267],[151,-584],[-40,-226],[135,-108],[45,-274],[319,-330],[390,35],[206,-130],[468,-423],[69,-267],[180,-292]],[[5190,79315],[619,-91],[188,-94],[590,71],[288,100],[274,-94],[1078,-181],[653,-229],[452,-43],[442,-122],[392,38],[484,-98],[478,42],[539,-3],[371,458],[284,50],[234,142],[86,139],[551,-81],[779,-309],[213,-16],[431,149],[361,12],[557,246],[133,136],[76,271],[207,364],[-5,404],[211,755],[414,632],[134,575],[-87,275],[-376,449],[-50,342],[-128,288],[2,212],[-398,724],[-389,336],[-368,463],[-147,274],[-501,436],[98,64],[-220,433],[-222,-130],[-1014,-401],[-559,-179],[-286,75],[-367,546],[-51,-87],[-476,-340],[-324,-298],[-537,-255],[-143,-27],[-289,-204],[-234,-82],[-96,-129],[-408,-273],[-23,-746],[-379,4],[-244,-84],[-334,75],[-363,-68],[-791,-492],[-296,-144],[-118,-135],[-503,277],[-138,-255],[239,-184],[30,-278],[-249,-409],[-224,-112],[-38,-874],[-67,-640],[-276,-749],[-158,-687],[-12,-234]],[[39731,69352],[-674,797],[-184,130],[-379,-145],[-138,18],[-162,218],[-75,233],[-287,170],[45,602],[-181,298],[-522,1493],[-222,381],[-388,531],[-399,836]],[[39781,68677],[-50,675]],[[35580,76905],[493,210],[293,-183],[399,-963],[623,300],[197,-394],[746,-374],[556,-1150],[422,-738],[375,-914],[-103,-637],[139,-363],[307,-198],[299,-621],[97,-342],[-396,-529],[-296,-657]],[[43537,70991],[103,510],[-731,52],[-163,-25],[-329,541],[-61,403],[58,163],[571,172],[-76,363],[-183,1796],[-62,1165],[-176,1327],[-171,941]]],"transform":{"scale":[0.0052608373143215575,-0.004800048000480004],"translate":[216.96076470257924,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/sz.json b/src/onegov/election_day/static/mapdata/2025/sz.json new file mode 100644 index 0000000000..49e06607e0 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/sz.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":1301,"properties":{"id":1301,"name":"Einsiedeln"},"arcs":[[-1,-2,-3,-4,-5,-6,-7,-8,-9,-10]]},{"type":"Polygon","id":1311,"properties":{"id":1311,"name":"Gersau"},"arcs":[[-11,-12,-13,-14]]},{"type":"Polygon","id":1321,"properties":{"id":1321,"name":"Feusisberg"},"arcs":[[9,-15,-16,-17]]},{"type":"Polygon","id":1322,"properties":{"id":1322,"name":"Freienbach"},"arcs":[[16,-18,-19,-20,0]]},{"type":"Polygon","id":1323,"properties":{"id":1323,"name":"Wollerau"},"arcs":[[17,15,-21]]},{"type":"Polygon","id":1331,"properties":{"id":1331,"name":"Küssnacht (SZ)"},"arcs":[[-22,-23]]},{"type":"Polygon","id":1341,"properties":{"id":1341,"name":"Altendorf"},"arcs":[[-24,-25,-26,1,19,-27]]},{"type":"Polygon","id":1342,"properties":{"id":1342,"name":"Galgenen"},"arcs":[[-28,-29,-30,-31,24]]},{"type":"Polygon","id":1343,"properties":{"id":1343,"name":"Innerthal"},"arcs":[[3,-32,-33,-34,-35,-36]]},{"type":"Polygon","id":1344,"properties":{"id":1344,"name":"Lachen"},"arcs":[[-37,-38,27,23]]},{"type":"Polygon","id":1345,"properties":{"id":1345,"name":"Reichenburg"},"arcs":[[-39,-40]]},{"type":"Polygon","id":1346,"properties":{"id":1346,"name":"Schübelbach"},"arcs":[[-41,29,-42,-43,-44,38,-45,32]]},{"type":"Polygon","id":1347,"properties":{"id":1347,"name":"Tuggen"},"arcs":[[42,-46,-47]]},{"type":"Polygon","id":1348,"properties":{"id":1348,"name":"Vorderthal"},"arcs":[[25,30,40,31,2]]},{"type":"Polygon","id":1349,"properties":{"id":1349,"name":"Wangen (SZ)"},"arcs":[[-48,45,41,28,37]]},{"type":"Polygon","id":1361,"properties":{"id":1361,"name":"Alpthal"},"arcs":[[-49,-50,6,-51]]},{"type":"Polygon","id":1362,"properties":{"id":1362,"name":"Arth"},"arcs":[[-52,-53,10,-54,21,-55]]},{"type":"Polygon","id":1363,"properties":{"id":1363,"name":"Illgau"},"arcs":[[-56,-57,-58]]},{"type":"Polygon","id":1364,"properties":{"id":1364,"name":"Ingenbohl"},"arcs":[[-59,-60,-61,-62,12]]},{"type":"Polygon","id":1365,"properties":{"id":1365,"name":"Lauerz"},"arcs":[[11,52,-63,-64,-65,58]]},{"type":"Polygon","id":1366,"properties":{"id":1366,"name":"Morschach"},"arcs":[[-66,60,-67,-68,-69]]},{"type":"Polygon","id":1367,"properties":{"id":1367,"name":"Muotathal"},"arcs":[[-70,67,-71,55,-72,-73,34,-74]]},{"type":"Polygon","id":1368,"properties":{"id":1368,"name":"Oberiberg"},"arcs":[[50,5,-75,71,57,-76]]},{"type":"Polygon","id":1369,"properties":{"id":1369,"name":"Riemenstalden"},"arcs":[[68,69,-77]]},{"type":"Polygon","id":1370,"properties":{"id":1370,"name":"Rothenthurm"},"arcs":[[7,49,-78,-79,-80]]},{"type":"Polygon","id":1371,"properties":{"id":1371,"name":"Sattel"},"arcs":[[-81,-82,-83,78,-84]]},{"type":"Polygon","id":1372,"properties":{"id":1372,"name":"Schwyz"},"arcs":[[66,59,64,-85,83,77,48,75,56,70]]},{"type":"Polygon","id":1373,"properties":{"id":1373,"name":"Steinen"},"arcs":[[84,63,-86,80]]},{"type":"Polygon","id":1374,"properties":{"id":1374,"name":"Steinerberg"},"arcs":[[81,85,62,51,-87]]},{"type":"Polygon","id":1375,"properties":{"id":1375,"name":"Unteriberg"},"arcs":[[35,72,74,4]]}]}},"arcs":[[[65667,85458],[-2631,-123],[-830,-32],[-34,31]],[[73669,72912],[-461,-29],[-326,-201],[-1,-225],[-347,136],[-198,435],[66,145],[-175,246],[-284,563],[118,247],[189,62],[259,227],[128,-102],[142,170],[163,-244],[396,354],[111,307],[31,381],[-158,83],[169,232],[28,279],[-291,93],[-209,-23],[-166,189],[-532,223],[-329,-364],[-258,246],[-128,53],[-67,188],[-215,279],[-255,192],[-125,25],[-22,246],[-290,222],[-86,256],[-227,276],[-194,570],[-97,386],[281,109],[-58,387],[53,223],[-144,145],[-134,295],[-146,14],[-114,261],[-188,185],[-360,213],[-459,-137],[-73,33],[15,397],[-63,251],[2,355],[-245,838],[21,258],[-76,194],[-344,227],[-306,72],[-244,-2],[-746,536],[-181,673],[79,231],[-397,176],[-534,489]],[[78134,63890],[-436,172],[-173,113],[-613,726],[-111,65],[-91,358],[-189,224],[-88,202],[-157,94],[3,273],[85,643],[-130,184],[-307,85],[-533,417],[-395,377],[-360,699],[-531,49],[-350,152],[45,303],[-3,672],[466,321],[393,812],[-9,363],[-173,467],[-48,395],[-139,215],[-614,482],[-7,159]],[[81134,55225],[57,214],[-78,246],[96,314],[-30,704],[-282,144],[-80,536],[-624,413],[-21,224],[-346,794],[-191,826],[-191,157],[-513,172],[-157,461],[-171,238],[-132,387],[-28,239],[-302,535],[-47,184],[-6,551],[-48,81],[-70,760],[164,485]],[[60806,54437],[5,175],[244,550],[143,746],[94,890],[159,208],[84,375],[120,161],[160,-7],[362,-228],[256,-65],[245,30],[158,-232],[4,-368],[142,-19],[210,126],[394,2],[201,-95],[222,-196],[272,-67],[340,165],[265,13],[428,-213],[409,-345],[95,-33],[196,146],[89,303],[197,127],[184,-60],[402,19],[451,253],[115,-22],[251,-232],[335,-100],[141,35],[322,222],[287,324],[372,6],[137,295],[320,321],[215,42],[1038,-120],[1338,-252],[344,108],[636,-507],[101,-112],[42,212],[1594,-665],[977,-1324],[371,-54],[374,-122],[382,20],[362,-76],[236,-134],[550,-15],[628,100],[336,306],[149,303],[133,117],[94,-49],[398,158],[161,-27],[332,149],[181,-7],[285,-141],[260,-332]],[[58095,52651],[426,-121],[437,-12],[364,77],[260,164],[104,178],[171,70],[151,417],[126,189],[196,135],[203,241],[273,448]],[[51846,60700],[95,-267],[324,-16],[937,-173],[417,76],[346,-228],[117,-185],[332,-87],[17,-382],[149,-520],[-5,-457],[200,11],[2112,-612],[29,-272],[119,-208],[35,-270],[-57,-109],[68,-403],[185,-122],[258,-974],[35,-300],[-40,-393],[-172,-593],[115,-316],[188,-171],[189,-401],[173,-258],[23,-375],[60,-44]],[[48421,74011],[157,-99],[460,64],[94,126],[344,-31],[39,-458],[330,-195],[613,314],[330,-219],[284,-124],[194,-515],[523,-510],[-64,-51],[223,-261],[-77,-579],[442,-2957],[264,-262],[-221,-549],[-143,-183],[-1,-146],[-186,-421],[-224,-189],[-187,-614],[-158,-210],[-65,-283],[-223,-305],[-123,-726],[84,-810],[-157,-509],[93,-201],[77,-437],[194,-239],[-91,-152],[71,-358],[165,-143],[101,-328],[-58,-412],[319,-227],[2,-112]],[[50659,78407],[-349,-158],[-28,-207],[-92,-32],[-132,202],[-259,-81],[-97,-176],[-338,-218],[-140,-247],[-252,-30],[-90,-222],[-267,-317],[-95,-306],[-169,-293],[-200,-561],[-127,-87],[-88,-503],[68,-439],[116,-377],[384,-156],[-83,-188]],[[62172,85334],[-236,766],[-87,390],[-202,194],[-263,-135],[-420,199],[-315,-94],[-328,-345],[-270,-419],[18,-329],[-174,-120],[-142,-380],[-18,-403],[-145,203],[-80,-13],[43,-357],[-200,-209],[76,-731],[-380,-89],[-465,-260],[-290,9],[-302,-161],[-281,-322],[-395,-110],[-418,171],[-329,-57],[-165,183],[-58,332],[-75,-84],[-533,-61],[-248,54],[-133,-98],[-144,-643],[-9,-837],[-38,-156],[-216,-275],[-147,-97],[-232,-420],[-66,-492],[-229,-230],[-265,-620],[-247,-169],[-141,-380],[-183,-35],[-296,247],[-274,-90],[-165,190],[-140,-10],[-121,-160],[-289,64],[-70,-270],[-164,-62],[-506,-12],[-7,-302],[-110,-79],[-100,118],[-539,69]],[[26399,39750],[-343,24],[-307,287],[-264,125],[-228,-36],[-245,-144],[-343,89],[-433,278],[-386,0],[-306,98],[-251,142],[-222,218],[-224,-57],[-170,79],[-590,143],[-112,191],[-190,-26],[-239,149],[-105,-22],[-385,-591],[-408,-383],[-4,-383],[-130,-77],[103,-230],[-107,-192]],[[28130,36154],[-367,332],[-193,247],[-131,270],[-50,345],[-188,357],[-164,581],[-403,337],[-71,189],[114,270],[-174,542],[-104,126]],[[28475,29147],[-731,1611],[-37,150],[-175,182],[-109,282],[-94,48],[-111,485],[-438,198],[-352,391],[-27,408],[182,293],[-146,232],[74,215],[195,295],[133,95],[205,352],[211,275],[91,640],[431,612],[353,243]],[[20510,39432],[81,-485],[25,-749],[-94,-418],[5,-1176],[-171,-664],[-162,-275],[-121,-674],[64,-194],[-256,-209],[-42,-277],[-636,-216],[-264,-199],[-440,-674],[-242,-10],[-720,-119],[-408,-377],[-266,-28],[-1234,-750],[-283,-5],[-395,-162],[-575,-97],[-298,-119],[-892,276],[-440,-3649],[5155,-2245],[3706,1069],[3812,0],[3056,2141]],[[49115,83063],[-1,-653],[37,-332],[87,26],[505,-151],[170,-824],[10,-249],[211,-146],[3,-608],[100,-147],[87,-371],[-99,-382],[67,-369],[316,-317],[51,-133]],[[54094,89232],[-59,-93],[-317,-104],[-77,187],[-97,-61],[-284,104],[-69,-275],[-145,-132],[-222,208],[-621,83],[-111,-112],[-122,-294],[-24,-460],[73,-310],[-1800,234],[4,-248],[-183,-10],[166,-370],[171,-186],[223,-25],[32,87],[375,-137],[-89,-432],[-65,-50],[-138,-383],[-564,-401],[53,-432],[-207,-258],[-242,-5],[-10,-248],[-211,44],[-115,137],[-141,-814],[-163,-1413]],[[62172,85334],[155,143],[-128,151],[376,489],[306,243],[36,302],[182,215],[159,296],[191,79],[409,525],[336,245],[76,190],[115,-50],[78,424],[-304,181],[-120,-193],[-200,10],[-397,228],[-1227,581],[-142,-30],[-188,213],[73,261],[-254,37],[-152,-54],[-220,150],[73,616],[-129,231],[-317,-14],[-361,105],[0,-120],[-346,-119],[-592,30],[-691,-105],[-7,505],[-343,278],[2,101],[-284,-49],[-181,-131],[-196,-3],[-353,-133],[-97,-131],[-92,60],[-407,-179],[-98,-127],[-494,-176],[-558,-274],[41,-124],[-211,8],[-614,-345],[-581,-357],[-305,-75],[85,-168],[-182,-42]],[[53719,94530],[527,-1223],[197,-245],[308,-188],[-25,-311],[-138,-121],[-100,-371],[-268,-136],[57,-106],[-8,-482],[85,-116],[-91,-199],[-253,-48],[-52,-331],[254,-16],[5,-183],[-220,-85],[86,-186],[-81,-440],[-96,-128],[188,-383]],[[69153,97660],[-603,665],[-317,423],[-361,569],[-2488,682],[-2617,-1161],[-5936,-2284],[-3112,-2024]],[[65667,85458],[290,248],[158,308],[-21,339],[72,396],[293,185],[312,304],[167,559],[-113,424],[-100,35],[-285,517],[81,359],[-85,278],[-46,391],[171,229],[23,363],[-105,133],[-137,382],[92,365],[114,79],[39,306],[201,209],[96,244],[-41,217],[74,156],[396,240],[269,80],[-95,220],[-149,92],[-104,289],[44,499],[1875,3756]],[[53719,94530],[-683,-444],[-634,-162],[-269,-479],[-211,-307],[-301,150],[-349,393],[-168,58],[-173,-63],[-169,-200],[-24,-557],[99,-187],[-168,-351],[-284,-143],[-155,-144],[-282,-134],[-335,30],[-264,-112],[-1041,-2350],[-326,-594],[-328,-202],[-394,-547],[53,-733],[-145,-513],[10,-357],[274,-630],[109,-422],[-49,-158],[119,-323],[459,-579],[712,-493],[190,-232],[-18,-241],[76,-411],[65,-30]],[[12485,47243],[302,119],[173,183],[252,420],[335,309],[214,363],[186,231],[47,210],[143,197],[278,6],[52,-65],[700,142],[278,154],[215,220],[220,104],[-20,969],[-93,549],[-192,682],[24,420],[-245,976],[2,660],[88,199],[-36,329],[128,320],[361,422],[128,478],[2,532],[3338,4796]],[[19365,61168],[-5201,3256],[-149,548],[-17,1003],[-320,263],[-358,-177],[-102,321],[-688,-428],[-243,-112],[-556,104],[18,212],[-280,-56],[-103,341],[-320,-203],[-61,137],[-626,312],[-502,128],[-111,-314],[-106,-598],[-202,-93],[-401,112],[-489,-20],[-168,-249],[-477,-317],[-126,-186],[-57,-395],[160,-264],[-59,-136],[-335,66],[-53,-141],[-205,-89],[-102,92],[-94,-104],[-164,19],[-61,-104],[-347,-97],[-100,-120],[-330,-93],[-343,-187],[-264,-252],[-213,-305],[-68,-4],[-349,-473],[-215,-386],[-144,-354],[-191,-264],[-90,-220],[-753,-844],[-99,-236],[-23,-254],[151,-317],[-159,-560],[91,-115],[65,-581],[105,-183],[-129,-272],[-96,-62],[11,-388],[-40,-343],[-316,-493],[2,-350],[-97,-194],[-170,-105],[-937,-983],[-229,-6],[-153,-205],[-249,-216],[-145,-354],[-336,-131],[-583,-486],[-64,-279],[142,-593],[95,-1293],[112,-308],[-35,-302],[282,-150],[968,-234],[178,-152],[5041,1852],[278,21],[278,-192],[74,-264],[193,26],[189,-161],[206,105],[277,-11],[330,-188],[760,-803],[-243,-328],[238,-291],[643,-408],[612,-478],[1867,-1989]],[[75887,89029],[-321,55],[13,90],[-273,1],[6,85],[-365,32],[-200,227],[-413,11],[-142,72],[13,675],[-173,79],[-371,624],[-677,4920]],[[75637,76820],[-271,468],[34,22],[-347,587],[-127,327],[-170,164],[-350,156],[-15,203],[93,277],[42,350],[24,706],[185,327],[-40,279],[145,323],[-207,527],[63,340],[-11,381],[110,504],[8,309],[107,116],[135,-48],[150,386],[-50,270],[44,261],[173,165],[-26,314],[58,102],[290,148],[-159,311],[116,180],[245,65],[50,245],[-16,436],[28,564],[-236,1091],[-19,505],[38,262],[156,586]],[[73669,72912],[28,130],[218,317],[437,309],[277,318],[-93,170],[-264,-163],[-99,247],[-195,215],[-30,127],[99,369],[166,140],[-37,405],[170,-3],[167,372],[105,65],[354,443],[143,38],[522,409]],[[72984,95900],[-898,123],[-455,122],[-666,257],[-522,270],[-414,263],[-398,298],[-478,427]],[[78384,91069],[-1,-73],[-254,11],[-880,-883],[-178,32],[-225,-574],[-58,36],[-237,-608],[-154,62],[-74,-278],[-436,235]],[[82267,86375],[-177,217],[-636,461],[-1276,1266],[-310,327],[-110,221],[-415,1153],[-168,289],[-791,760]],[[82470,78857],[85,567],[-67,245],[77,239],[-7,375],[-234,452],[-89,499],[-120,436],[-236,317],[6,496],[-59,181],[-130,86],[-125,250],[-13,175],[143,194],[66,277],[388,327],[130,412],[349,71],[201,359],[53,399],[-101,313],[-520,848]],[[75637,76820],[295,328],[18,117],[574,459],[421,379],[385,215],[341,96],[483,340],[414,-86],[309,-3],[422,67],[417,-87],[483,-239],[442,-278],[89,315],[99,88],[240,-99],[145,15],[166,556],[-35,171],[501,-48],[137,-151],[487,-118]],[[90436,69727],[-134,-473],[-497,46],[-460,-823],[280,-377],[37,-387],[-44,-160],[-11,-460],[-179,-511],[-129,-118],[-166,-5],[-103,173],[-316,121],[-304,-113],[-614,271],[-144,290],[-17,233],[-299,-39],[-278,73],[-262,-124],[-154,-207],[-64,-209],[-439,-240],[-304,272],[-169,13],[-198,-88],[-263,-21],[-1183,302],[-184,-885],[-148,-147],[236,-284],[-102,-131],[-116,61],[-392,-132],[-250,408],[-630,202],[-49,247],[-95,-23],[-406,224],[-325,61],[-198,183],[-292,176],[52,166],[-47,200],[-266,73],[-162,-61],[-139,-219],[-215,21],[-292,-165],[-291,76],[-159,-112],[144,-221],[-443,-296],[-30,-114],[183,-150],[-44,-432],[-173,-148],[-145,-498],[-245,-350],[-44,-309],[-185,-466],[-436,-231]],[[95218,68741],[-119,-65],[-426,-508],[-481,-278],[-329,3],[-615,-96],[-241,-193],[-112,0],[-257,-158],[-598,-92],[-261,75],[-338,196],[-144,305],[-42,318],[-110,183],[-51,363],[-183,153],[-134,329],[-158,171],[31,99],[-214,181]],[[82800,40447],[-310,639],[-21,168],[368,108],[12,405],[413,171],[461,91],[464,341],[-91,455],[1,263],[-386,686],[64,137],[-128,872],[9,335],[135,324],[269,277],[139,52],[348,-80],[257,263],[272,130],[434,-104],[419,195],[123,-415],[412,-42],[40,-126],[636,127],[238,158],[187,308],[953,693],[605,204],[71,115],[357,174],[236,353],[27,252],[371,586],[183,40],[498,304],[54,122],[282,-43],[142,122],[132,763],[-33,517],[139,406],[-19,327],[-78,120],[75,335],[100,121],[107,775],[247,234],[-2,253],[268,837],[311,239],[286,545],[120,364],[45,306],[143,256],[190,-25],[103,222],[-38,333],[62,208],[-34,364],[49,95],[-215,446],[222,77],[465,512],[25,127],[238,365],[-81,303],[20,172],[263,33],[255,334],[593,595],[266,171],[163,180],[-133,182],[-172,-38],[-130,183],[-326,54],[-452,14],[-247,97],[-269,183],[-153,29],[-614,375],[-576,74],[-118,249],[-320,-23],[-124,251],[32,825],[161,71],[102,241],[158,160],[66,542],[141,79],[124,440],[125,256],[509,266],[86,-9],[138,289],[511,228],[305,239],[219,89],[99,260],[-99,402],[1,261],[-73,30],[-179,501],[163,159],[136,253],[-34,709],[142,110],[198,294],[90,399]],[[79037,42159],[417,-40],[298,-374],[268,64],[411,-415],[278,-411],[376,-221],[69,-171],[293,-216],[421,-217],[321,79],[421,44],[190,166]],[[81134,55225],[-90,-263],[-28,-600],[-304,-140],[-284,-218],[-476,-557],[360,-205],[92,-103],[273,-108],[147,-355],[-99,-155],[94,-254],[257,-196],[179,-12],[132,-129],[269,-109],[-123,-713],[95,-390],[-296,-818],[128,-518],[-105,-459],[-101,-179],[-249,-178],[-29,-382],[-503,-628],[-134,-223],[-21,-452],[328,-1507],[-229,-452],[-241,-206],[-61,-253],[-516,-570],[-178,-296],[-240,-129],[-31,-343],[-178,-500],[65,-466]],[[76355,96430],[-1966,-419],[-466,-78],[-469,-37],[-470,4]],[[78384,91069],[-361,388],[-1198,2101],[-275,1454],[-195,1418]],[[94379,87656],[398,13],[30,-807],[-370,102],[-60,-411],[-293,56],[-60,-110],[128,-67],[-60,-365],[-92,23],[-87,-531],[-174,44],[7,-224],[-510,-253],[-173,23],[-253,-211],[-345,69],[-153,-146],[-86,-349],[35,-129],[-75,-279],[-284,-558],[-36,-260],[-127,-210],[53,-608],[-28,-691],[137,-400],[0,-467],[-75,-565],[-253,120],[-330,31],[-137,-58],[-217,-279],[71,-404],[-7,-304],[-107,-180],[-71,-295],[94,-146],[-100,-189],[-113,-781],[133,-116],[296,-442],[511,-460],[93,-205],[333,-257],[394,96],[318,-152],[133,-281],[304,-284],[234,-9],[168,-154],[198,-391],[320,-91]],[[94091,75114],[519,492],[187,108],[151,311],[167,224],[154,557],[-61,281],[138,222],[2192,4684],[382,804],[244,456],[1835,2893],[-359,443],[-86,-154],[-934,647],[197,400],[-453,384],[-659,458],[-484,271],[-556,246],[-696,195],[-275,-220],[-212,-9],[-27,-227],[-506,125],[-96,-595],[-371,92],[-103,-546]],[[82470,78857],[-49,-159],[7,-426],[112,-107],[85,-307],[-81,-313],[1,-492],[265,-193],[27,-204],[227,-10],[280,-394],[196,-18],[136,-134],[189,97],[99,-50],[193,150],[7,155],[136,82],[197,-135],[176,112],[99,-266],[181,17],[87,-190],[197,152],[294,-241],[218,45],[352,-385],[298,71],[109,-256],[366,-51],[311,-626],[531,76],[89,-165],[-59,-140],[251,-254],[48,-322],[280,-84],[162,-244],[306,-43],[68,-90],[301,-83],[91,-157],[244,-200],[179,-7],[103,-179],[167,-116],[4,-222],[175,-228],[-83,-185],[19,-729],[77,-180],[31,-584],[77,-186],[-21,-203],[83,-378],[128,-151]],[[84486,89464],[-82,-205],[-183,66],[-37,-280],[-115,-332],[-321,-488],[-136,-407],[-257,-237],[-179,19],[-53,-355],[-654,-444],[36,-125],[-222,-96],[92,-118],[-108,-87]],[[92978,89144],[-113,-32],[-2562,-333],[-671,-47],[-518,1],[-676,102],[-492,187],[-621,366],[-781,516],[-1000,503],[-178,-777],[-143,-452],[-737,286]],[[94379,87656],[-1341,138],[-27,24],[-103,912],[70,414]],[[95218,68741],[-129,514],[-177,375],[-298,29],[-376,256],[-107,12],[-311,677],[-22,169],[107,365],[-14,190],[80,330],[211,460],[29,508],[78,421],[129,329],[-105,182],[-84,634],[195,297],[-162,373],[-171,252]],[[84108,98083],[302,-2191],[295,-607],[-180,-175],[75,-177],[229,-152],[104,-760],[-1,-439],[-366,-192],[-369,-119],[-87,-603],[107,-122],[82,-686],[-216,-149],[-300,-304],[-39,-302],[476,-164],[-227,-18],[-38,-288],[116,-88],[-39,-137],[253,-241],[-103,-465],[330,-83],[-26,-157]],[[92978,89144],[-165,430],[-118,1001],[-508,3162],[16,19],[1268,-369],[548,3817],[20,260],[106,-97],[716,406],[-237,639],[-133,262],[-178,218],[-212,159],[-297,97],[-247,-9],[-1515,-378],[-375,-14],[-2181,482],[-5378,-1146]],[[84108,98083],[-7753,-1653]],[[48694,51070],[127,-397],[278,-1073],[170,-185],[355,-76],[7,-120],[-284,-252],[-244,1],[-36,-210],[389,-347],[345,-91],[166,-226],[-86,-194],[-41,-361],[120,-156],[117,-412],[-44,-182],[-147,-61],[-12,-202],[-122,-206],[113,-206],[-131,-170],[-356,-104],[-26,-234],[-129,-127],[78,-165],[-80,-194],[178,-190],[77,-392],[113,-36],[64,-254],[239,-103],[24,-268],[139,-197],[-123,-102],[28,-303],[81,5],[37,-246],[-159,-641],[77,-377],[269,-40],[411,133],[492,-156],[451,-366],[23,-201],[166,-548],[55,-400],[433,-186],[255,81],[576,9],[189,68],[373,22],[326,184],[415,66],[219,102],[470,1],[410,343],[-17,141],[-191,294],[-32,375],[-221,578],[112,563],[439,659],[1,358],[530,643],[128,365]],[[51846,60700],[-383,-2],[-171,-118],[-363,-114],[-163,17],[-782,-100],[75,-448],[-68,-826],[161,-654],[195,-963],[-58,-214],[-325,-606],[-136,-342],[-51,-480],[-127,-559],[-38,-714],[92,-248],[33,-321],[71,-139],[4,-316],[-166,-352],[-543,-581],[-142,-374],[41,-330],[-104,-235],[-298,-263],[112,-149],[-18,-199]],[[56278,45104],[180,424],[77,633],[-113,474],[87,372],[323,298],[-39,290],[-139,320],[-170,866],[119,713],[4,724],[192,93],[221,549],[195,238],[528,536],[-23,226],[137,424],[238,367]],[[31306,46815],[-372,112],[-183,155],[37,776],[-65,238],[0,649],[37,40],[-207,491],[-237,167],[-81,444],[-180,107],[-102,424],[-137,69],[42,687],[-105,193],[41,299],[-357,634],[18,323],[-62,449],[68,176],[-67,189],[13,225],[-133,122],[-234,53],[-5,430],[-63,312],[-325,151],[58,622],[-61,334],[-20,508],[-89,215],[-87,472],[-5,546]],[[26399,39750],[184,60],[131,186],[255,162],[133,-157],[575,-315],[478,74],[266,-63],[157,175],[214,449],[123,356],[299,277],[160,366],[-125,603],[-144,398],[-5,492],[91,650],[142,229],[199,126],[594,213],[162,443],[388,539],[161,-51],[19,206],[211,10],[45,305],[180,-20],[14,1352]],[[12485,47243],[570,-49],[260,-217],[1481,-2184],[451,-396],[358,-209],[422,-849],[317,-176],[249,-306],[120,-473],[211,-183],[448,-611],[424,-138],[69,-273],[213,-192],[318,-700],[106,-108],[299,-56],[316,107],[503,-88],[343,-167],[547,-543]],[[28443,57427],[-140,333],[101,300],[49,347],[216,499],[-159,542],[-59,1005],[-191,531],[-151,-30],[-517,79],[-385,-162],[-546,169],[-652,-124],[-245,11],[-207,205],[-277,9],[-526,-544],[-25,-114],[-722,-153],[-120,86],[-765,-199],[-849,39],[-235,-396],[-164,51],[-234,-167],[-2275,1424]],[[50148,32916],[195,-155],[327,-156],[294,-6],[673,-298],[55,49],[751,-5],[365,-166],[79,16],[221,-242],[81,8],[199,-466],[123,-150],[7,-195],[110,-176],[344,-239],[179,-287],[151,-137],[147,-309],[340,-207],[111,14],[187,-299],[410,-304],[224,68],[312,14],[0,97],[423,403],[260,-23],[307,-237],[212,9],[197,-212],[428,8],[103,-200],[293,-123],[615,-63],[450,-103],[342,84],[273,-4],[151,87],[448,-48],[200,267],[290,36],[315,811],[226,60],[349,336],[452,44],[139,273],[402,102],[130,87],[-390,533],[112,332],[271,180],[505,142]],[[63543,33230],[-769,883],[-276,103],[-497,552],[-175,257],[-46,188],[138,193],[-541,216],[-295,292],[-239,33],[-83,91],[-385,35],[-154,321],[-318,365],[-290,83],[-115,107],[-59,-300],[-560,-638],[-211,-177],[-329,-886],[-94,78],[-333,-73],[-359,162],[-134,-117],[-222,132],[-314,50],[-321,-57],[-420,102],[-258,-74],[-611,-33],[-319,215],[-202,-42],[-906,224],[-204,7],[-432,-131],[-221,63],[-29,-137],[-407,-298],[-118,-34],[215,-559],[-300,20],[-308,-62],[-108,-226],[-970,165],[-222,-74],[-73,-144],[-192,-133],[-179,-243],[-324,-574],[22,-254],[152,15]],[[63536,32166],[7,1064]],[[35471,38788],[-394,-160],[-993,-849],[-365,-158],[-243,-162],[-390,-162],[-462,-273],[-286,8],[-194,-123],[-1033,-335],[-224,181],[-355,110],[-562,23],[-133,-132],[-324,-69],[-286,-128],[-324,-275],[-527,-196],[-246,66]],[[40637,32016],[-143,150],[-63,200],[167,90],[24,264],[108,235],[108,71],[-66,124],[292,214],[5,121],[183,155],[-154,102],[462,245],[-209,538],[-146,-153],[-261,780],[-237,-271],[-501,747],[-66,-34],[-218,474],[-301,-170],[-52,290],[39,330],[-197,26],[-19,376],[-254,27],[-572,-144],[-638,-120],[-131,-72],[-115,113],[162,300],[419,232],[-75,40],[-137,351],[26,122],[261,276],[-105,241],[-135,-88],[-28,166],[-179,198],[-255,-215],[19,180],[-254,221],[-169,-42],[-377,503],[-125,-13],[-203,330],[-82,-249],[-129,-80],[-206,-280],[-228,-183],[-411,54]],[[35451,28000],[1249,184],[164,-40],[418,117],[75,289],[-62,781],[-51,6],[-120,398],[-126,227],[56,224],[353,321],[139,3],[220,175],[378,99],[80,262],[216,17],[192,101],[244,-25],[5,242],[168,-39],[66,-350],[123,17],[102,193],[386,241],[131,208],[153,-105],[-36,152],[371,236],[241,-11],[51,93]],[[28475,29147],[1541,1080],[1848,999],[2416,-906],[993,-983],[178,-1337]],[[31339,46857],[-33,-42]],[[35678,41240],[-3393,4722],[-173,2],[10,223],[-465,30],[3,282],[-212,42],[3,290],[-112,26]],[[35471,38788],[-92,305],[-160,266],[23,165],[-80,197],[536,287],[-51,233],[63,422],[226,-53],[5,316],[-106,-23],[-191,257],[34,80]],[[35451,28000],[-457,-2117],[403,-1978],[204,-4927],[2676,210],[265,72],[214,-62],[586,-481],[76,-172],[-57,-132],[259,25],[40,90],[689,-133],[229,58],[168,-77],[121,69]],[[45760,29047],[-47,50],[-344,-70],[-3310,117],[83,302],[-28,426],[-295,316],[-22,207],[163,290],[-109,309],[-70,-47],[-230,103],[-208,-70],[-38,407],[182,310],[-117,68],[-328,-151],[-372,-76],[152,386],[-185,92]],[[49549,20795],[116,689],[101,206],[-8,190],[79,377],[187,430],[285,445],[122,408],[-48,300],[35,549],[-16,454],[33,379],[250,250],[-150,318],[-255,663],[-172,110],[-229,-135],[-343,214],[-633,-36],[-125,-223],[-357,-169],[-279,-325],[-72,-148],[-184,-119],[-34,153],[70,271],[-126,202],[63,275],[-88,268],[-301,526],[-248,23],[49,374],[-193,200],[55,90],[-6,375],[138,473],[-191,22],[-191,-112],[-554,63],[-260,178],[-309,44]],[[40867,18445],[512,149],[22,180],[167,413],[179,80],[24,305],[156,295],[-51,313],[357,367],[230,350],[211,200],[217,408],[161,600],[197,86],[788,-846],[326,-307],[456,-266],[50,78],[399,-168],[343,-68],[426,173],[365,-232],[300,94],[359,173],[436,-238],[526,-183],[198,79],[114,256],[253,149],[278,-285],[429,3],[254,192]],[[49549,20795],[139,-253],[305,-3],[385,-182],[288,19],[134,-149],[301,-109],[30,-109],[284,-98],[551,-64],[429,114],[537,-364],[185,-185],[379,28],[317,-1599],[-129,-904],[48,-553],[15,-755],[-44,-510],[49,-920],[-18,-261],[166,-525],[357,-101],[353,-244],[235,67],[349,-223],[101,40],[351,-607],[352,-76],[59,-86]],[[50148,32916],[-140,-92],[-287,39],[-265,-78],[-68,66],[-450,-442],[-247,-181],[-143,52],[-468,-178],[-143,8],[-37,168],[-160,179],[-281,-159],[-93,-236],[-142,-120],[-271,-573],[-114,-657],[-425,87],[86,-391],[-197,-189],[-117,-289],[-216,-233],[-207,-417],[-3,-233]],[[73608,35904],[-98,-127],[-326,-159],[-176,-228],[-211,-170],[-118,-210],[-268,-13],[-120,-199],[-322,-220],[-515,-192],[-205,-153],[-606,226],[-392,-21],[-202,-182],[-130,16],[-133,-188],[-358,-2],[-278,-83],[-151,-225],[-524,-13],[-165,76],[-280,-203],[-410,63],[-274,-55],[-191,26],[-308,-259],[-138,-28],[-186,-256],[-483,-300],[-294,48],[-420,-80],[-615,-191],[-284,-129],[-160,6],[-260,-224],[-471,-89]],[[79037,42159],[26,-151],[-30,-537],[-137,-577],[-95,1],[-260,-375],[-34,-196],[-139,-138],[-100,-397],[47,-390],[-118,-69],[-268,-513],[-5,-253],[-123,-66],[-150,-294],[3,-520],[-170,-395],[-102,-619],[-203,-229],[-206,-651],[-130,-215],[-144,-474],[-152,1],[-166,-121],[-523,-145],[-402,96],[-180,118],[-204,416],[-294,43],[-229,127],[-179,225],[-286,47],[-341,-40],[-135,36]],[[56057,12183],[-67,176],[379,-54],[98,88],[182,392],[187,147],[339,15],[142,92],[-63,112],[126,369],[114,96],[259,-205],[208,245],[237,-158],[245,102],[183,187],[53,152],[2,512],[133,44],[18,-142],[505,-346],[333,237],[829,653],[88,-107],[197,225],[87,-66],[51,237],[92,-95],[307,156],[145,205],[482,114],[156,205],[67,212],[371,82],[329,344],[589,-529],[-23,-423],[600,-1511],[235,-178],[292,-21],[162,-141],[495,-229],[213,-49],[234,-173],[688,141],[-30,276],[417,424],[294,479],[-38,227],[315,385],[857,495],[153,-2],[238,168],[501,428],[313,358],[582,-828],[969,-349],[176,-334],[482,-101],[443,-36],[98,-477],[-23,-133],[254,-240],[191,-359],[43,-339],[-63,-732],[-137,-450],[-45,-439],[224,-282],[-149,-360],[-217,-138],[59,-911],[155,-417],[241,-351],[564,-1557],[302,-502],[152,-609],[568,208],[498,344],[240,567],[317,233],[155,319],[-12,181],[147,-88],[141,-205],[1,-182],[105,-301],[7,-736],[-80,-293],[-6,-349],[-88,-382],[8,-367],[57,-132],[-54,-344],[137,-440],[32,-234],[-36,-335],[-61,-1073],[-106,-723],[19,-583],[301,-818],[597,-823],[258,108],[-50,401],[232,432],[429,211],[296,389],[124,385],[-37,377],[176,217],[-142,214],[91,72],[596,118],[188,-41],[313,-209],[424,-44],[43,140],[496,152],[1067,892],[238,360],[153,511],[562,477],[262,85],[140,-23],[252,92],[-1,84],[383,-91],[305,53],[57,355],[73,122],[203,-58],[23,146],[256,-16],[-45,193],[80,121],[-72,165],[675,578],[386,73],[352,-280],[-13,412],[236,31],[129,-69],[111,272],[143,163],[12,172],[448,260],[145,-141],[313,302],[48,214],[371,388],[205,-31],[53,-97],[41,265],[238,357],[303,-111],[142,207],[153,24],[378,375],[147,6],[69,170],[287,138],[246,315],[192,-7],[223,301],[262,24],[38,246],[153,7],[27,171],[271,193],[400,-76],[191,293],[237,186],[300,128],[85,391],[377,16],[166,-114],[277,51],[178,236],[243,38],[249,-144],[70,224],[283,-94],[251,167],[133,-54],[220,130],[146,471],[-24,214],[-227,584],[-266,190],[-184,-138],[-435,723],[-96,267],[270,-12],[-119,382],[-292,292],[-22,368],[-94,252],[216,405],[-23,146],[166,552],[-43,90],[114,369],[221,405],[53,403],[231,150],[98,931],[-20,452],[69,550],[102,247],[216,153],[79,265],[228,122],[170,360],[143,-84],[144,171],[310,150],[96,450],[-181,-95],[-167,90],[-134,-61],[-389,194],[-149,171],[-364,-16],[-276,169],[-142,-34],[-328,209],[-265,51],[-229,175],[-298,342],[-155,501],[-196,92],[-126,207],[-174,46],[-51,277],[-160,74],[136,105],[42,289],[-178,-129],[-179,-282],[-311,-309],[-1749,3485],[-518,962],[1099,520],[306,230],[97,754],[-98,203],[-45,-146],[-349,-24],[-113,-292],[-247,452],[-51,311],[-131,-102],[-234,242],[-33,254],[-242,206],[-42,335],[-114,405],[-150,309],[-40,274],[-98,231],[-293,441],[-346,268],[-435,467],[-61,156],[-224,131],[-80,-402],[-290,369],[-364,628],[-33,254],[26,340],[-275,613],[-205,55],[-52,104],[-380,231],[68,53],[-72,229],[-165,1329],[75,202],[-10,210],[-111,398],[-452,230],[-386,237],[-870,678],[-325,-129],[-141,2],[-103,135],[-278,-67]],[[73608,35904],[16,347],[-98,487],[-127,292],[-11,318],[254,622],[186,145],[145,457],[36,462],[-130,106],[61,483],[-43,53],[95,837],[-68,523],[25,235],[-181,11],[-7,1145],[40,41],[-73,388],[328,289],[-117,211],[378,791],[78,336],[-1439,-287],[-288,-33],[-388,-239],[-227,-73],[-452,38],[-192,-133],[-171,80],[-274,-305],[-74,-451],[0,-730],[-80,-457],[47,-280],[-161,-280],[37,-103],[-144,-702],[-328,-415],[-22,-244],[-218,-120],[-206,-521],[-156,35],[-219,-318],[-172,-350],[-54,79],[-334,-57],[-12,-159],[-124,-4],[-433,-579],[133,-377],[132,-213],[-226,-60],[-131,-271],[-166,28],[-1353,-1231],[-110,328],[12,169],[-283,152],[-211,382],[-182,225],[-8,268],[-171,55],[169,162],[-68,333],[95,58],[69,377],[102,90],[-5,533],[324,163],[124,498],[262,172],[101,209],[502,315],[70,539],[-253,430],[-162,537],[62,257],[129,107],[84,512],[-105,124],[3,236],[-87,398],[13,443],[165,799],[74,71],[-738,435],[-99,157],[-88,608],[117,417],[-64,43],[71,246],[164,140],[72,170],[-65,293],[-14,346],[114,119],[53,215],[-13,474],[-59,427],[214,806],[-123,83],[-301,7],[-418,-171],[-265,-46],[31,240],[-231,-61],[-66,138],[-134,-82],[-49,325],[-222,-7],[-350,-121],[-472,-476],[-500,-282],[54,296],[-162,227],[-88,349],[-184,394],[29,389],[-236,73],[-452,584],[12,507],[-709,704],[-278,1168],[-1160,610]],[[56278,45104],[1820,-2743],[576,-726],[399,-587],[104,100],[208,-415],[77,-257],[-24,-159],[352,-406],[1030,-1306],[41,-202],[533,-674],[116,-623],[349,-377],[159,-591],[84,-198],[1029,-361],[807,-1810],[-395,-539]],[[40867,18445],[243,-101],[450,49],[136,-140],[217,49],[191,-77],[262,-11],[411,-276],[315,-78],[80,-77],[366,-110],[378,-170],[130,-7],[165,-168],[311,171],[518,-200],[507,-36],[301,-234],[179,-29],[261,-165],[388,102],[270,190],[281,-20],[280,225],[367,105],[88,-45],[214,92],[515,-193],[618,302],[159,133],[568,74],[64,-26],[66,-346],[129,-409],[116,-214],[268,-189],[85,-252],[-46,-562],[134,-192],[54,-294],[361,-1137],[17,-421],[75,-217],[-604,-1156],[200,-527],[-1,-232],[103,-207],[61,-414],[98,-84],[58,-256],[212,-114],[495,-412],[161,-303],[182,-159],[226,-481],[69,-225],[190,-11],[620,453],[324,-48],[145,-100],[190,166],[165,-40],[26,225],[256,114],[184,254],[-16,411],[219,89],[114,141],[5,160],[339,387],[-24,243],[137,15],[-1,205],[161,-52],[364,352],[40,248]],[[46055,51057],[143,-76],[397,-709],[176,29],[233,-155],[324,-116],[453,39],[360,535],[301,187],[252,279]],[[42389,64125],[607,-457],[417,-582],[143,-1089],[-138,-434],[82,-836],[-84,-188],[166,-355],[-4,-260],[108,-526],[-107,-106],[418,-601],[194,-60],[195,111],[128,-399],[158,-138],[268,-2],[78,-299],[204,-468],[185,-189],[273,-486],[128,-139],[-1,-179],[97,-301],[-214,-1014],[-87,-237],[-165,-210],[-259,-488],[370,-330],[209,-422],[31,-526],[162,-428],[132,-225],[-24,-236],[77,-237],[-115,-441],[34,-291]],[[48421,74011],[-107,-58],[134,-247],[43,-243],[-269,66],[-111,-257],[34,-154],[-154,-68],[113,-253],[-105,-122],[272,-165],[-79,-153],[-162,-46],[21,-243],[-221,-254],[-145,-425],[-16,-531],[-116,-59],[53,-146],[-312,-111],[-72,-146],[-149,113],[-199,-239],[49,-212],[-128,-5],[151,-194],[-194,12],[-161,-389],[-140,45],[-71,-191],[-101,54],[-156,-128],[-100,-244],[35,-127],[-232,-31],[214,-683],[-162,9],[125,-232],[-96,-100],[-671,-38],[-277,-212],[-426,55],[-305,-52],[-172,-109],[133,-844],[-123,-273],[-270,-223],[-390,-499],[-308,-207],[-709,-1327]],[[33243,55790],[167,210],[91,-133],[515,-248],[151,-147],[139,-318],[10,-263],[-80,-112],[161,-537],[144,-180],[24,150],[220,497],[265,-134],[81,-267],[254,-243],[78,-285],[354,146],[89,-142],[176,-74],[127,-181],[77,41],[100,-299],[221,-144],[172,126],[83,-196],[133,118],[516,-35],[230,-202],[36,79],[197,-73],[234,4],[158,-180],[322,26],[127,226],[147,46],[289,-151],[231,19],[106,111],[77,-456],[-22,-385],[351,44],[267,127],[-47,-139],[166,-365],[410,-149],[201,-401]],[[32344,58659],[17,-130],[182,-184],[152,-475],[-114,-492],[237,-440],[18,-138],[315,-710],[92,-300]],[[42389,64125],[-612,-1145],[-79,-1121],[-441,-276],[-135,-173],[-113,44],[-552,-371],[-425,-3],[-429,74],[-287,-25],[-47,73],[-658,9],[-484,240],[-1828,43],[-501,-165],[-195,-733],[-1220,-456],[-285,8],[-336,259],[-471,-346],[-134,-224],[-238,-217],[-126,-738],[-449,-223]],[[40991,51321],[182,83],[16,127],[407,254],[121,273],[202,69],[211,318],[70,193],[123,-497],[259,305],[-27,404],[279,69],[295,216],[-16,-350],[487,-318],[113,79],[175,-181],[220,102],[179,-120],[222,80],[331,-191],[406,-93],[36,150],[155,95],[-213,385],[5,245],[399,-344],[77,-314],[141,-281],[38,-479],[86,-579],[85,36]],[[40991,51321],[-158,-607],[-205,-186],[-139,-224],[-215,-193],[-127,-306],[-11,-222],[-189,-412],[175,-76],[-283,-276],[-99,29],[-130,-255],[77,-337],[-78,-131],[-309,-16],[-43,-593],[-50,-201],[48,-259],[-222,-150],[-37,-313],[-115,-158],[206,-126],[-14,-173],[-179,-247],[-192,-66],[18,150],[-187,-90],[-70,-510],[-337,-443],[-177,-295],[-371,-129],[-262,-18],[-131,-129],[78,-363],[-1585,-2756]],[[33243,55790],[-132,-69],[136,-266],[-8,-245],[-87,-270],[109,-689],[184,-5],[89,-500],[-74,-116],[90,-104],[120,-483],[-34,-319],[35,-923],[217,-871],[43,-75],[-195,-73],[-56,-236],[244,-286],[125,-409],[-102,-276],[-108,-51],[-419,61],[-212,137],[-167,-137],[-11,-344],[239,-188],[162,-222],[121,-290],[-416,-135],[-467,0],[-274,-294],[-106,-276],[-156,32],[-329,-86],[-353,-358],[-34,-374],[-78,-193]],[[32344,58659],[-353,-69],[-264,-247],[-395,-203],[-400,20],[-172,115],[-534,-673],[-127,-69],[-520,-101],[-121,-152],[-632,-66],[-383,213]]],"transform":{"scale":[0.005973096340550453,-0.004800048000480004],"translate":[181.34816952064762,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/tg.json b/src/onegov/election_day/static/mapdata/2025/tg.json new file mode 100644 index 0000000000..5130b0c50b --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/tg.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":4401,"properties":{"id":4401,"name":"Arbon"},"arcs":[[-1,-2,-3]]},{"type":"Polygon","id":4406,"properties":{"id":4406,"name":"Dozwil"},"arcs":[[-4,-5,-6]]},{"type":"Polygon","id":4411,"properties":{"id":4411,"name":"Egnach"},"arcs":[[-7,1,-8,-9,-10,-11],[-12]]},{"type":"Polygon","id":4416,"properties":{"id":4416,"name":"Hefenhofen"},"arcs":[[-13,-14,-15,-16,-17,3,-18]]},{"type":"Polygon","id":4421,"properties":{"id":4421,"name":"Horn"},"arcs":[[-19]]},{"type":"Polygon","id":4426,"properties":{"id":4426,"name":"Kesswil"},"arcs":[[-20,-21,-22,4,16,-23]]},{"type":"Polygon","id":4431,"properties":{"id":4431,"name":"Roggwil (TG)"},"arcs":[[7,0,-24]]},{"type":"Polygon","id":4436,"properties":{"id":4436,"name":"Romanshorn"},"arcs":[[-25,-26,-27,12]]},{"type":"Polygon","id":4441,"properties":{"id":4441,"name":"Salmsach"},"arcs":[[10,-28,13,26,-29]]},{"type":"Polygon","id":4446,"properties":{"id":4446,"name":"Sommeri"},"arcs":[[-30,-31,-32,-33,22,15]]},{"type":"Polygon","id":4451,"properties":{"id":4451,"name":"Uttwil"},"arcs":[[17,5,21,-34,24]]},{"type":"Polygon","id":4461,"properties":{"id":4461,"name":"Amriswil"},"arcs":[[14,27,9,-35,-36,-37,29]]},{"type":"Polygon","id":4471,"properties":{"id":4471,"name":"Bischofszell"},"arcs":[[-38,-39,-40,-41,-42]]},{"type":"Polygon","id":4476,"properties":{"id":4476,"name":"Erlen"},"arcs":[[-43,-44,-45,-46,-47,30,36]]},{"type":"Polygon","id":4486,"properties":{"id":4486,"name":"Hauptwil-Gottshaus"},"arcs":[[40,-48,-49]]},{"type":"Polygon","id":4495,"properties":{"id":4495,"name":"Hohentannen"},"arcs":[[-50,-51,43,-52,38]]},{"type":"Polygon","id":4501,"properties":{"id":4501,"name":"Kradolf-Schönenberg"},"arcs":[[-53,49,37,-54,-55,-56,-57]]},{"type":"Polygon","id":4506,"properties":{"id":4506,"name":"Sulgen"},"arcs":[[-58,-59,44,50,52]]},{"type":"Polygon","id":4511,"properties":{"id":4511,"name":"Zihlschlacht-Sitterdorf"},"arcs":[[35,-60,47,39,51,42]]},{"type":"Polygon","id":4536,"properties":{"id":4536,"name":"Basadingen-Schlattingen"},"arcs":[[-61,-62,-63]]},{"type":"Polygon","id":4545,"properties":{"id":4545,"name":"Diessenhofen"},"arcs":[[-64,61,-65,-66,-67]]},{"type":"Polygon","id":4546,"properties":{"id":4546,"name":"Schlatt (TG)"},"arcs":[[-68,64,60]]},{"type":"Polygon","id":4551,"properties":{"id":4551,"name":"Aadorf"},"arcs":[[-69,-70,-71,-72,-73]]},{"type":"Polygon","id":4561,"properties":{"id":4561,"name":"Felben-Wellhausen"},"arcs":[[-74,-75,-76,-77,-78]]},{"type":"Polygon","id":4566,"properties":{"id":4566,"name":"Frauenfeld"},"arcs":[[-79,-80,-81,-82,-83,73,-84,-85,68]]},{"type":"Polygon","id":4571,"properties":{"id":4571,"name":"Gachnang"},"arcs":[[-86,79]]},{"type":"Polygon","id":4590,"properties":{"id":4590,"name":"Hüttlingen"},"arcs":[[-87,-88,-89,76,-90]]},{"type":"Polygon","id":4591,"properties":{"id":4591,"name":"Matzingen"},"arcs":[[-91,69,84,-92,-93]]},{"type":"Polygon","id":4601,"properties":{"id":4601,"name":"Neunforn"},"arcs":[[-94,-95,-96]]},{"type":"Polygon","id":4606,"properties":{"id":4606,"name":"Stettfurt"},"arcs":[[-97,92,-98,-99]]},{"type":"Polygon","id":4611,"properties":{"id":4611,"name":"Thundorf"},"arcs":[[-100,-101,97,91,83,77,88,-102]]},{"type":"Polygon","id":4616,"properties":{"id":4616,"name":"Uesslingen-Buch"},"arcs":[[94,-103,-104,81,-105]]},{"type":"Polygon","id":4621,"properties":{"id":4621,"name":"Warth-Weiningen"},"arcs":[[-106,-107,74,82,103,-108]]},{"type":"Polygon","id":4641,"properties":{"id":4641,"name":"Altnau"},"arcs":[[-109,-110,-111,-112]]},{"type":"Polygon","id":4643,"properties":{"id":4643,"name":"Bottighofen"},"arcs":[[-113,-114,-115,-116]]},{"type":"Polygon","id":4646,"properties":{"id":4646,"name":"Ermatingen"},"arcs":[[-117,-118,-119,-120,-121,-122]]},{"type":"Polygon","id":4651,"properties":{"id":4651,"name":"Gottlieben"},"arcs":[[116,-123,-124]]},{"type":"Polygon","id":4656,"properties":{"id":4656,"name":"Güttingen"},"arcs":[[19,32,-125,111,-126]]},{"type":"Polygon","id":4666,"properties":{"id":4666,"name":"Kemmental"},"arcs":[[-127,-128,-129,-130,-131,-132,-133,-134]]},{"type":"Polygon","id":4671,"properties":{"id":4671,"name":"Kreuzlingen"},"arcs":[[115,-135,128,-136,-137]]},{"type":"Polygon","id":4681,"properties":{"id":4681,"name":"Langrickenbach"},"arcs":[[124,31,46,-138,-139,-140,108]]},{"type":"Polygon","id":4683,"properties":{"id":4683,"name":"Lengwil"},"arcs":[[-141,129,134,114,-142,138,-143]]},{"type":"Polygon","id":4691,"properties":{"id":4691,"name":"Münsterlingen"},"arcs":[[113,-144,109,139,141]]},{"type":"Polygon","id":4696,"properties":{"id":4696,"name":"Tägerwilen"},"arcs":[[123,-145,135,127,-146,117]]},{"type":"Polygon","id":4701,"properties":{"id":4701,"name":"Wäldi"},"arcs":[[-147,-148,118,145,126]]},{"type":"Polygon","id":4711,"properties":{"id":4711,"name":"Affeltrangen"},"arcs":[[-149,-150,99,-151,-152,-153]]},{"type":"Polygon","id":4716,"properties":{"id":4716,"name":"Bettwiesen"},"arcs":[[-154,-155,-156,-157,-158]]},{"type":"MultiPolygon","id":4721,"properties":{"id":4721,"name":"Bichelsee-Balterswil"},"arcs":[[[-159,-160,-161,71,-162]],[[-163,-164]]]},{"type":"Polygon","id":4723,"properties":{"id":4723,"name":"Braunau"},"arcs":[[152,-165,-166,-167,-168,-169]]},{"type":"Polygon","id":4724,"properties":{"id":4724,"name":"Eschlikon"},"arcs":[[-170,-171,-172,158,-173]]},{"type":"Polygon","id":4726,"properties":{"id":4726,"name":"Fischingen"},"arcs":[[163,-174,159,171,-175,-176]]},{"type":"Polygon","id":4741,"properties":{"id":4741,"name":"Lommis"},"arcs":[[157,-177,98,100,149,-178]]},{"type":"Polygon","id":4746,"properties":{"id":4746,"name":"Münchwilen (TG)"},"arcs":[[-179,155,-180,-181,169]]},{"type":"Polygon","id":4751,"properties":{"id":4751,"name":"Rickenbach (TG)"},"arcs":[[-182,-183]]},{"type":"Polygon","id":4756,"properties":{"id":4756,"name":"Schönholzerswilen"},"arcs":[[55,-184,165,-185,-186]]},{"type":"Polygon","id":4761,"properties":{"id":4761,"name":"Sirnach"},"arcs":[[170,180,-187,-188,-189,174]]},{"type":"Polygon","id":4776,"properties":{"id":4776,"name":"Tobel-Tägerschen"},"arcs":[[177,148,168,153]]},{"type":"Polygon","id":4781,"properties":{"id":4781,"name":"Wängi"},"arcs":[[172,161,70,90,96,176,156,178]]},{"type":"Polygon","id":4786,"properties":{"id":4786,"name":"Wilen (TG)"},"arcs":[[-190,187,-191,181]]},{"type":"Polygon","id":4791,"properties":{"id":4791,"name":"Wuppenau"},"arcs":[[166,183,54,-192]]},{"type":"Polygon","id":4801,"properties":{"id":4801,"name":"Berlingen"},"arcs":[[-193,-194,-195,-196]]},{"type":"MultiPolygon","id":4806,"properties":{"id":4806,"name":"Eschenz"},"arcs":[[[-197,-198,-199,-200]],[[-201]]]},{"type":"Polygon","id":4811,"properties":{"id":4811,"name":"Herdern"},"arcs":[[-202,-203,105,-204,-205]]},{"type":"Polygon","id":4816,"properties":{"id":4816,"name":"Homburg"},"arcs":[[-206,-207,-208,-209,-210,201,-211]]},{"type":"Polygon","id":4821,"properties":{"id":4821,"name":"Hüttwilen"},"arcs":[[-212,203,107,102,93,-213,-214,196]]},{"type":"Polygon","id":4826,"properties":{"id":4826,"name":"Mammern"},"arcs":[[210,204,211,199,-215,-216]]},{"type":"Polygon","id":4831,"properties":{"id":4831,"name":"Müllheim"},"arcs":[[-217,208,-218,86]]},{"type":"Polygon","id":4841,"properties":{"id":4841,"name":"Pfyn"},"arcs":[[216,89,75,106,202,209]]},{"type":"Polygon","id":4846,"properties":{"id":4846,"name":"Raperswilen"},"arcs":[[195,-219,119,147,-220,206,-221]]},{"type":"Polygon","id":4851,"properties":{"id":4851,"name":"Salenstein"},"arcs":[[218,194,-222,120]]},{"type":"Polygon","id":4864,"properties":{"id":4864,"name":"Steckborn"},"arcs":[[215,-223,192,220,205]]},{"type":"Polygon","id":4871,"properties":{"id":4871,"name":"Wagenhausen"},"arcs":[[66,-224,197,213,-225]]},{"type":"Polygon","id":4881,"properties":{"id":4881,"name":"Amlikon-Bissegg"},"arcs":[[87,-226,-227,-228,-229,150,101]]},{"type":"Polygon","id":4891,"properties":{"id":4891,"name":"Berg (TG)"},"arcs":[[-230,-231,130,140,-232]]},{"type":"Polygon","id":4901,"properties":{"id":4901,"name":"Birwinken"},"arcs":[[231,142,137,45,58,-233]]},{"type":"Polygon","id":4911,"properties":{"id":4911,"name":"Bürglen (TG)"},"arcs":[[56,185,-234,-235,229,232,57]]},{"type":"Polygon","id":4921,"properties":{"id":4921,"name":"Bussnang"},"arcs":[[164,151,228,-236,233,184]]},{"type":"Polygon","id":4941,"properties":{"id":4941,"name":"Märstetten"},"arcs":[[-237,226,-238,132]]},{"type":"Polygon","id":4946,"properties":{"id":4946,"name":"Weinfelden"},"arcs":[[131,230,234,235,227,236]]},{"type":"Polygon","id":4951,"properties":{"id":4951,"name":"Wigoltingen"},"arcs":[[133,237,225,217,207,219,146]]}]}},"arcs":[[[90372,50084],[189,-15],[10,-274],[100,-148],[107,-21],[-14,-377],[-192,-660],[2,-139],[273,-184],[377,-197],[181,-182],[505,-408],[-52,-635],[-107,38],[-63,-340],[197,-429],[14,-522],[-93,-35],[-109,-187],[-263,-9],[-382,246],[-124,-52],[9,-251],[295,-212],[-11,-207],[251,-77],[-10,-182],[-160,-595],[-10,-197],[-181,241],[-28,-36],[249,-794],[122,-185],[-57,-66],[390,-1041],[63,185],[344,20],[382,-291],[240,-33],[30,-194],[-73,-385],[9,-149],[-194,-263]],[[90973,52487],[-192,-158],[-216,-379],[44,-65],[-160,-570],[-77,-1231]],[[92588,40842],[183,-395],[308,-178],[218,991],[183,513],[45,200],[117,85],[414,543],[118,408],[117,122],[231,44],[-18,256],[295,220],[-126,859],[-18,454],[40,289],[232,391],[127,-182],[115,38],[57,153],[97,-125],[86,41],[79,313],[-111,256],[-149,145],[128,254],[-142,462],[-208,444],[-163,238],[-179,138],[-172,315],[-174,80],[-328,-214],[-205,43],[-132,149],[-139,44],[-175,386],[-298,301],[-68,439],[-183,349],[-429,527],[-36,184],[-198,181],[-71,199],[-99,52],[-177,307],[-175,187],[-187,291],[-154,520],[-164,185],[-1,157],[-126,-14]],[[78724,63884],[-103,-163],[-201,-1042],[-56,-50],[127,-317],[457,867],[457,504],[157,-473],[327,434],[-6,47],[296,1],[8,110],[378,-15],[52,-315],[210,-42]],[[81165,66409],[-716,976],[-257,-588],[14,-170],[-240,-208],[-45,236],[-89,-51],[23,-148],[-148,84],[-51,-170],[27,-317],[-93,-313],[-90,34],[-38,-151],[3,-401],[62,-457],[-108,-468],[-90,-179],[-464,-282],[-141,48]],[[80827,63430],[-51,216],[74,107],[-7,403],[43,131],[223,178],[112,14],[334,563],[-487,662],[277,218],[-180,487]],[[90973,52487],[-39,302],[-206,165],[-65,158],[-152,54],[-103,215],[-116,33],[-246,247],[-22,89],[-282,290],[-200,259],[-227,381],[-257,357],[-28,169],[-203,294],[-196,367],[6,106],[-119,351],[6,261],[78,239],[8,309],[-45,136],[-110,-164],[-87,108],[-134,317],[-193,165],[-84,156]],[[86095,41742],[92,124],[91,277],[-16,206],[81,82],[104,438],[125,-7],[80,383],[58,486],[59,-16],[33,437],[147,104],[98,439],[399,-19],[49,376],[177,-174],[35,-491],[248,47],[35,-99],[418,44],[374,401],[-30,277],[165,66],[-39,223],[-12,668],[-318,93],[49,996],[66,267],[93,-33],[34,237],[103,112],[18,183],[-102,100],[-1,250],[92,677],[-136,96],[72,452],[123,-80],[94,262],[73,438],[234,227],[553,-84],[-1,-74],[413,-109],[47,60]],[[82885,50982],[54,-500],[7,-467],[39,-291],[-1,-326],[-142,-504],[271,-263],[33,-495],[70,-190],[250,-322],[-27,-165],[57,-130],[282,186],[500,-124],[329,-202],[125,39],[204,174],[68,-109],[-55,-993],[-64,-4],[-86,-201],[10,-123],[-134,-151],[-142,33],[-71,123],[-168,-8],[-58,-375],[-186,-93],[-317,-681],[219,-76],[118,-98],[-37,-455],[-112,15],[-13,-257],[-110,-336],[-98,-33],[-131,106],[-120,-588],[-108,0],[-227,123],[-277,-23],[-78,-578],[-3,-223],[-67,-158],[-71,-493],[74,-310],[101,-155],[151,297],[-20,156],[109,322],[248,176],[191,-194],[227,-132],[174,-210],[140,-7],[225,-160],[302,32],[318,-142],[168,-14],[55,348],[-43,457],[189,-8],[493,-252],[34,115],[341,-323]],[[80807,54255],[0,-145],[-90,-47],[-94,-363],[722,-462],[-8,-46],[430,-260],[-45,-536],[418,-122],[219,-150],[414,-148],[-107,-325],[-73,-395],[292,-274]],[[87957,57851],[-389,-192],[-294,-112],[-267,-302],[-72,-237],[-355,-190],[-21,-341],[-116,-255],[-223,-156],[-221,-460],[-147,-93],[-434,162],[-320,237],[-340,107],[-769,-217],[-376,-2],[-265,-119],[-433,-26],[-35,-80],[-270,-200],[-322,-103],[21,-181],[-424,-72],[-130,-89],[-158,-299],[-143,-41],[-54,-203],[-241,-46],[-125,-116],[-110,73],[-117,-43]],[[84726,44851],[217,71],[156,-33],[-14,-142],[290,-272],[-46,-192],[-14,-435],[-49,-134],[-437,373],[18,160],[-89,366],[-75,92],[43,146]],[[81992,56742],[-67,-63],[-55,394],[38,323],[-64,361],[33,302],[-70,214],[53,440],[-126,30],[-13,263],[-269,-3],[-272,-60],[-30,236],[90,164],[37,379],[-174,1029]],[[80681,54612],[71,101],[239,-93],[44,115],[53,436],[24,607],[-80,155],[-21,341],[709,-129],[287,12],[53,359],[-68,226]],[[77374,59387],[213,-938],[206,171],[113,-506],[713,268],[390,-123],[128,38],[-2,-464],[87,-175],[176,-515],[-54,-54],[44,-210],[-147,-238],[185,-89],[65,-1314],[245,-222],[190,-52],[90,-96],[270,-132],[395,-124]],[[77784,65335],[-103,-1223],[51,-70],[-145,-256],[9,-140],[196,-382],[-159,-315],[-98,-390],[89,-210],[-50,-420],[-282,115],[-53,-712],[-58,10],[50,-683],[-10,-273],[158,42],[151,-597],[-64,-429],[-92,-15]],[[78724,63884],[93,362],[-192,348],[-66,469],[-220,304],[-555,-32]],[[81103,60751],[-64,122],[-294,-46],[-3,327],[145,435],[53,378],[-64,148],[111,430],[7,278],[-87,137],[-99,337],[19,133]],[[96513,42080],[-114,-221],[114,-348],[-148,-512],[284,-313],[-254,-1079],[200,-106],[-39,-334],[525,-149],[-101,-243],[28,-278],[382,-78],[366,-144],[12,51],[429,-333],[44,258],[338,-316],[-146,-315],[-7,-352],[-73,-302],[78,-261],[257,353],[1179,1355],[125,219],[-104,18],[-343,247],[-177,289],[-130,136],[-55,171],[-257,408],[18,163],[-211,177],[-15,145],[-164,208],[-157,116],[-188,-43],[-102,107],[-68,-99],[-396,292],[-646,618],[4,116],[-281,122],[-163,141],[-44,116]],[[79421,72868],[-190,-564],[-109,131],[-106,-213],[-182,224],[-249,-508],[-147,207],[-180,-431],[-247,-744],[-315,-485],[36,-86],[236,-205],[384,-636],[-447,-1202],[-232,-749],[-12,-536],[-49,-453],[8,-443],[-98,-392]],[[81650,69897],[-128,53],[-676,752],[-30,127],[-168,173],[-81,302],[-153,69],[-151,287],[-154,77],[-450,786],[-238,345]],[[81165,66409],[184,369],[-252,309],[257,524],[-269,408],[92,344],[-65,71],[173,454],[91,80],[139,308],[135,621]],[[77522,65783],[103,-486],[159,38]],[[86095,41742],[276,-303],[160,-104],[87,228],[410,-69],[179,-174],[50,27],[54,-227],[-22,-605],[33,-247],[-39,-509],[-118,-299],[-131,-55],[-254,61],[-126,-154],[42,-121],[-91,-497],[542,-488],[-155,-502],[-124,78],[-274,-366],[-162,-583],[-33,-241],[212,-219],[296,228],[306,-21],[97,336],[129,228],[345,61],[148,-69],[19,108],[198,8],[-142,-586],[211,-153],[108,-142],[20,-181],[173,-187],[146,-345],[96,-68],[264,18],[128,-129],[233,-626],[126,-282],[-55,-395],[268,-436],[122,-15],[343,-282],[-96,532],[6,366],[103,-8],[145,112],[114,-59],[139,401],[-18,337],[99,176],[-62,527],[-48,31],[164,262],[35,499],[-211,357],[83,152],[232,206],[86,250],[-56,234],[160,161],[96,517],[84,130],[-51,131],[81,268],[-64,224],[62,273],[203,-146],[177,-51],[111,387],[169,368],[102,-70],[86,644],[340,-33],[-23,101],[150,120]],[[84868,66687],[-78,-275],[-57,59],[-44,-182],[158,-149],[-87,-211],[-191,-318],[121,-255],[-188,-279],[-305,-694],[44,-81],[-105,-115],[48,-85],[-327,-283],[-142,-310],[-390,569],[-63,-129],[-60,-488],[-276,-614],[-183,-298],[-57,-431],[-225,-194],[-173,-221],[-250,-427],[-138,43],[-245,-26],[-255,128],[-217,-422],[-80,-248]],[[87812,59037],[96,1110],[115,525],[126,7],[107,212],[-56,593],[-86,230],[-35,368],[279,338],[-30,196],[22,383],[-31,390],[-122,217],[-111,-61],[-207,173],[1,312],[-196,138],[-166,44],[-200,215],[-42,117],[-217,170],[-365,113],[-160,119],[-311,356],[-148,242],[-152,111],[-116,168],[-389,395],[-249,220],[-245,159],[-56,90]],[[81992,56742],[160,40],[-23,271],[114,233],[126,-8],[206,-154],[90,157],[202,19],[252,-137],[373,-145],[70,72],[113,-138],[178,-55],[307,27],[40,-98],[297,-27],[91,237],[-76,333],[83,87],[-87,189],[-233,104],[402,331],[337,57],[26,-158],[238,262],[71,-88],[224,-52],[56,165],[161,-71],[-52,329],[73,-53],[38,188],[-82,44],[7,157],[148,121],[128,-111],[62,99],[381,-178],[70,95],[323,224],[113,2],[176,-176],[222,119],[210,-70],[205,52]],[[80681,54612],[126,-357]],[[87957,57851],[-188,591],[64,170],[-21,425]],[[73616,62166],[404,-39],[33,-265],[244,35],[30,-395],[151,34],[32,185],[180,-6],[-46,-458],[432,124],[111,-517],[415,98],[88,-257],[346,151],[194,-462],[134,-150],[22,-441],[260,79],[49,-585],[291,102],[14,-73],[374,61]],[[73431,62793],[185,-627]],[[74781,65877],[11,-637],[-70,25],[-102,-651],[-755,-5],[7,-228],[-101,-14],[-130,-195],[-150,4],[27,-306],[-25,-253],[107,-586],[-120,-88],[-49,-150]],[[77522,65783],[-157,288],[-149,10],[-254,-135],[-107,101],[-220,-401],[-120,-126],[-184,259],[-15,167],[-120,443],[-312,43],[-350,-223],[-145,49],[-157,337],[-177,30],[-291,-248],[17,-500]],[[84868,66687],[-319,205],[-411,406],[-380,308],[-303,411],[-120,210],[-157,-82],[-87,145],[-128,61],[-270,346],[-352,335],[-169,225],[-260,247],[-262,393]],[[77262,48047],[224,-42],[117,319],[-2,243],[179,-63],[222,39],[223,-75],[160,738],[529,-161],[166,-140],[155,-279],[57,-303],[341,-426],[82,407],[20,429],[-58,522],[-119,358],[211,308],[308,71],[-80,332],[-83,160],[264,209],[-31,131],[148,129],[196,-78],[218,-170],[99,345],[99,-133],[-43,-408],[116,-262],[163,-108],[427,-179],[96,234],[11,166],[256,-18],[504,-202],[281,9],[99,641],[68,192]],[[72026,50517],[281,111],[309,25],[113,93],[1,-114],[211,63],[20,-62],[249,88],[1,72],[252,-11],[-32,-121],[436,-111],[1,157],[565,89],[28,-202],[586,-625],[27,-227],[238,-57],[-15,-631],[123,-21],[79,-603],[-1,-335],[111,-169],[339,306],[127,348],[131,77],[232,-733],[148,116],[438,752],[57,-511],[181,-234]],[[73616,62166],[-58,-350],[-253,-216],[-336,-34],[87,-758],[-60,-604],[75,-719],[-212,23],[86,-887],[96,27],[74,-493],[-87,-54],[70,-309],[123,-20],[-64,-373],[-284,-165],[-494,-100],[1,-291],[-462,71],[21,-521],[-243,-155],[-134,-164],[94,-192],[86,-42],[14,-1124],[-197,-11],[-36,-831],[211,20],[-6,-251],[55,-46],[44,-400],[118,18],[26,-442],[220,-21],[8,-252],[196,-981],[-387,-187],[11,-217],[-57,-227],[-31,-363],[95,-8]],[[66725,43006],[-269,-232],[-143,71],[-165,660],[220,318],[-421,703],[-65,-177],[-161,337],[-186,191],[-23,128],[-159,-141],[-41,78],[-185,32],[-144,-146],[-82,-738],[-105,-374],[-124,-59],[-470,-581],[-304,-204],[-145,-181],[-103,-31],[-218,-352],[2,-311],[-107,-174],[-2,-444],[-91,117],[12,-519],[45,-232],[-69,-212],[-143,-750],[49,-480]],[[69995,41746],[-72,94],[-295,-591],[-195,-310],[68,-124],[-153,-156],[-57,-187],[110,-394],[-233,-46],[82,-412],[-209,-248],[-266,-453],[-165,43],[-155,119],[-162,220],[-209,479],[-134,187],[-382,265],[-141,246],[-37,166],[-14,501],[13,463],[-66,328],[-341,640],[-257,430]],[[72256,41648],[-62,287],[-126,95],[-174,-221],[-141,-775],[-334,-1175],[-63,-132],[-286,564],[-127,-181],[-34,222],[-179,391],[16,164],[168,217],[-311,528],[145,212],[-54,89],[-196,-10],[13,-135],[-112,-351],[-260,7],[-144,302]],[[70750,34549],[177,29],[379,190],[342,430],[34,-70],[108,161],[6,293],[-108,27],[44,571],[-43,16],[10,323],[118,510],[50,-93],[120,365],[273,249],[349,467],[243,187],[113,317],[253,407],[-102,76],[-196,449],[-126,25],[-137,258],[133,121],[-143,479],[-342,433],[-70,614],[-112,360],[133,-95]],[[63128,39303],[327,14],[96,109],[86,-768],[17,-378],[150,-749],[660,414],[60,171],[573,-575],[-128,-531],[99,-191],[446,517],[255,-477],[156,189],[188,-231],[190,142],[227,-125],[132,32],[195,-75],[277,232],[-195,-400],[-23,-144],[-186,-264],[-8,-204],[51,-305],[113,-231],[15,-426],[-101,-154],[359,-187],[-102,-581],[229,-96],[296,-284],[62,302],[-59,161],[163,494],[23,-57],[418,674],[177,-155],[117,35],[141,177],[350,210],[271,-135],[130,-204],[116,263],[424,-305],[-5,-688],[601,-20],[99,269],[140,-219]],[[71418,49845],[266,101],[342,256],[0,315]],[[68852,51122],[359,173],[353,-120],[260,5],[506,250],[177,33],[66,-731],[107,35],[31,-214],[-37,-180],[68,-224],[34,-316],[154,-74],[37,225],[290,-135],[161,-4]],[[66801,58241],[-2,-498],[-177,-179],[101,-402],[-168,-156],[63,-256],[-83,-72],[30,-152],[161,-299],[182,-562],[-330,-423],[-102,-424],[22,-304],[57,-190],[-951,-1001],[-15,-190],[124,-60],[-81,-253],[172,-109],[50,-219],[173,-42],[198,105],[119,188],[100,-296],[61,98],[120,-220],[115,182],[114,-52],[33,-141],[177,38],[243,174],[7,-88],[189,83],[22,-207],[269,191],[287,104],[269,44],[198,-649],[123,97],[66,-236],[111,77],[36,-148],[-56,-340],[24,-332]],[[71221,62952],[-254,-246],[-79,134],[-92,-53],[-160,-268],[-221,-185],[-152,-70],[105,-446],[-243,0],[-39,-134],[-270,-437],[-151,-55],[-136,-309],[-90,58],[-129,-135],[30,-300],[214,-216],[179,-465],[1,-213],[-137,-144],[-165,-78],[-294,-372],[-188,-36],[-112,-279],[-112,-148],[-177,38],[-155,-253],[-351,-42],[-181,-91],[-48,363],[-105,58],[-632,-153],[-276,-234]],[[73431,62793],[-120,626],[41,195],[-98,353],[-67,12],[-129,312],[-20,169],[-210,-47],[36,-256],[-122,-46],[38,-198],[-87,20],[62,-660],[100,-18],[21,-336],[-185,-36],[-187,48],[-20,236],[-137,-109],[-3,264],[-121,-15],[-80,291],[160,15],[10,422],[-187,440],[-96,-128],[35,-164],[-131,-194],[-18,-506],[-70,-75],[-367,-145],[-258,-311]],[[79187,41358],[-208,220],[-182,-11],[-134,-99],[-126,-191],[-109,-321],[-23,-217],[43,-283],[218,-567],[-42,-188],[-352,137],[-409,258],[-175,19],[-79,-90],[-157,-385],[-90,-16],[-173,151],[-536,641],[-342,373],[-167,417],[-40,244],[-17,420],[35,485],[-53,248],[-128,43],[-102,-80],[-130,-275],[-168,-616],[-103,-292],[-256,-428],[-133,-132],[-109,-3],[-49,183],[59,169],[-215,317],[-364,292],[-480,528],[-112,-6],[-540,-718],[-59,11],[-180,329],[-71,9],[-299,-355],[-258,-176],[-116,245]],[[70750,34549],[162,-217],[164,-82],[202,-24],[159,109],[133,-382],[-52,-226],[123,-320],[116,-467],[186,-112],[324,-289],[132,357],[210,-166],[659,-106],[113,51],[291,-78],[258,206],[290,517],[139,61],[293,265],[207,-21],[29,302],[278,193],[425,103],[45,108],[30,548],[188,441],[72,77],[302,-206],[116,-32],[158,75],[137,-71],[-7,-241],[115,-478],[164,26],[-22,-159],[662,-150],[102,-189],[130,134],[57,-38],[253,-426],[118,140],[279,206],[236,293],[159,421],[238,260],[156,234],[-14,371],[75,340],[199,204],[542,485],[106,279],[-52,200],[139,112],[-43,232],[104,69],[195,453],[247,111],[-63,306],[-148,521],[-4,438],[78,628],[-21,175],[-181,640],[-159,331],[-245,85],[-214,-194],[-404,-707],[-120,-137],[-85,29],[-41,290],[99,416],[8,352],[-90,133]],[[67002,49453],[116,-428],[-28,-54],[95,-328],[145,-87],[192,28],[56,-977],[-116,-247],[-297,-137],[34,-375],[-307,-199],[-185,-221],[125,-437],[49,-557],[-11,-293],[-120,-577],[-90,-727],[7,-476],[58,-355]],[[68852,51122],[-77,-37],[-184,-270],[-311,-175],[-328,-356],[-351,-276],[-227,-26],[-198,-274],[31,-105],[-205,-150]],[[69995,41746],[224,305],[-107,315],[401,458],[-28,46],[223,304],[-42,230],[-71,1003],[-35,257],[-143,673],[-103,694],[122,79],[-79,464],[46,284],[374,197],[-82,546],[104,23],[-23,831],[100,118],[55,-96],[23,532],[266,178],[1,388],[204,4],[-7,266]],[[67002,49453],[-84,-88],[-377,-186],[-313,202],[-344,-7],[-72,98],[-7,292],[-165,-30],[-96,230],[-180,-187],[-307,152],[-113,-135],[-56,88],[-94,-243],[-55,86],[-90,-271],[-152,96],[-15,-102],[-125,56],[-119,-79],[-55,150],[-274,-302],[-222,239],[-103,314],[-420,-804],[-144,13],[-19,-375],[-76,-116],[-193,512],[-351,997]],[[61665,41474],[200,-162],[-84,-593],[159,-121],[44,66],[92,800],[341,-201],[-323,-1598],[186,-326],[132,-24],[170,-315],[85,-511],[139,259],[315,-137],[140,395],[-133,297]],[[59978,40700],[465,177],[218,271],[217,82],[190,131],[236,28],[55,135],[243,318],[63,-368]],[[60582,50591],[74,-679],[-129,-15],[-175,-226],[-51,-434],[-116,-15],[110,-945],[104,-379],[-332,-308],[29,-616],[231,117],[51,-505],[-16,-255],[50,-131],[-88,-417],[125,-77],[106,-351],[202,-135],[95,-147],[97,141],[195,-36],[94,110],[195,34],[67,-323],[-54,-355],[-128,-441],[-183,-119],[-118,-182],[-108,-42],[-290,-308],[-247,-464],[-31,-593],[-136,-159],[-93,44],[-185,-276],[73,-95],[-192,-318],[-26,-377],[-104,-6],[116,-285],[184,-323]],[[62381,50053],[-478,1356],[-150,255],[-336,311],[-138,85],[-51,-795],[-371,51],[-44,-46],[129,-438],[-96,-230],[-44,62],[-220,-73]],[[65511,59903],[-281,-48],[-11,-358],[-298,-197],[-166,-176],[-76,-210],[82,-451],[-341,-261],[-47,-220],[-186,33],[13,-369],[-100,-13],[-65,-492],[8,-221],[-265,27],[-69,-269],[-332,157],[-5,299],[-238,-251],[-342,-44],[-69,279],[-747,-326],[34,-1106],[-189,-1187],[17,-396],[56,-2],[45,-567],[61,-73],[107,-527],[190,-368],[84,-548],[187,-789],[169,-482],[54,-402],[-410,-292]],[[66801,58241],[-32,517],[-196,-87],[-98,387],[-238,-282],[-123,-21],[-123,423],[-104,250],[-109,141],[-110,391],[-157,-57]],[[79187,41358],[90,567],[-159,207],[52,425],[189,293],[17,457],[299,-194],[74,15],[112,230],[119,-263],[108,591],[124,-27],[-52,299],[-155,-16],[-322,122],[-133,108],[-289,411],[-238,449],[-328,267],[10,220],[-199,288],[-169,-495],[169,-159],[-81,-399],[-148,118],[-61,-302],[-185,90],[-188,-933],[-295,130],[-224,-301],[-186,-181],[-42,-471],[-253,129],[-44,80],[-194,0],[-148,71],[2,-267],[-362,-237],[-225,-50],[-69,-87],[-12,229],[-283,-31],[-92,133],[-428,-4],[-99,53],[-51,336],[-203,-85],[-130,703],[-204,76],[-72,165],[45,253],[168,246],[174,-325],[108,201],[110,62],[13,134],[107,27],[128,157],[124,-159],[77,-214],[106,-23],[22,-483],[116,-116],[178,49],[8,394],[-107,147],[39,527],[-65,159],[390,228],[-24,297],[23,256],[147,492],[102,187],[-321,673],[1365,760]],[[6396,91744],[60,-258],[69,-548],[119,-520],[-20,-105],[23,-731],[294,10],[-99,-175],[46,-133],[-107,-86],[-88,-668],[4,-361],[135,-61],[-1,-516],[-49,-552],[58,-503],[70,-177],[226,-273],[304,-12],[383,86],[127,-42],[-25,-336],[-304,-87],[16,-305],[129,-431],[12,-183],[-56,-317],[-110,-388],[16,-368],[336,-157],[-51,-292]],[[16013,90761],[42,647],[-24,495],[-192,-47],[-153,110],[-379,34],[-176,288],[-200,12],[-131,140],[-252,167],[6,-93],[-131,-237],[-133,54],[-202,-227],[-132,-71],[-133,102],[-123,-83],[-52,-187],[-142,105],[-147,-92],[-29,-292],[-140,65],[-19,143],[-178,11],[-38,84],[191,252],[10,151],[-95,86],[-32,334],[-102,7],[-441,397],[93,204],[-80,311],[-304,-71],[230,352],[95,345],[-72,624],[-177,76],[-340,74],[-41,215],[-418,61],[-6,-207],[-99,15],[143,-561],[-1006,-214],[-11,758],[-448,-39],[-92,110],[-385,287],[-7,-196],[123,-875],[-26,-157],[-116,-112],[-339,163],[50,-179],[-241,-197],[-329,-22],[19,-419],[-875,-367],[-34,-153],[-310,174],[-359,-41],[-146,-87],[-347,252],[169,-529],[-59,-16],[50,-407],[-157,-32],[42,-361],[-280,-151]],[[7913,83255],[393,-239],[166,366],[219,-137],[329,109],[333,272],[-102,-244],[61,-28],[33,-753],[242,-97],[232,-244],[114,681],[180,215],[293,-59],[4,365],[376,-108],[55,339],[184,-25],[84,61],[117,254],[110,624],[11,-121],[328,250],[275,802],[227,97],[231,342],[281,-96],[208,38],[243,-365],[200,34],[127,247],[36,229],[118,221],[269,193],[207,286],[354,825],[73,44],[-26,785],[83,133],[17,373],[-21,459],[138,759],[86,710],[330,-158],[217,-43],[457,104],[208,6]],[[16013,90761],[154,-9],[265,112],[159,12]],[[4138,98922],[-81,-157],[15,-481],[59,-437],[76,-275],[321,115],[71,-319],[-27,-2116],[234,-1248],[360,84],[32,-34],[198,431],[158,200],[27,139],[106,-59],[31,-769],[282,-901],[72,-288],[178,-471],[146,-592]],[[16032,94329],[-249,-250],[-378,-183],[-267,-4],[-270,107],[-213,138],[-712,635],[-419,462],[-327,285],[-286,318],[-224,350],[-202,544],[-268,411],[-376,416],[-591,539],[-241,197],[-300,187],[-539,257],[-188,30],[-564,11],[-417,80],[-269,132],[-485,297],[-426,62],[-761,-88],[-243,-79],[-313,-175],[-224,-182],[-486,-505],[-165,-80],[-302,2],[-283,-62],[-220,31],[-211,110],[-281,300],[-194,300]],[[16591,90876],[344,54],[-44,132],[55,243],[-242,271],[-320,246],[-247,31],[104,395],[-150,141],[55,422],[-47,72],[81,464],[-23,567],[-125,415]],[[4138,98922],[-373,380],[-341,215],[-528,418],[-154,64],[-177,-58],[-197,-314],[-214,-657],[-125,-263],[-388,-543],[-293,-544],[-212,-289],[-300,-231],[-356,-377],[-123,-89],[-202,-42],[2,-606],[41,-417],[-34,-405],[-164,-1014],[162,-737],[401,-414],[121,-163],[280,-178],[155,-262],[21,-538],[65,-438],[139,49],[43,-568],[-41,-292],[-152,3],[-2,-505],[39,-525],[140,-345],[63,48],[37,-189],[-39,-435],[150,-473],[213,-216],[123,-553],[182,-161],[5,-554],[256,58],[192,-723],[-21,-388],[289,-181],[321,-327],[26,-109],[195,17],[443,-97],[40,-219],[207,11],[73,-404],[223,-195],[119,-323],[554,-539],[87,-124],[145,335],[174,259],[327,201],[72,-406],[189,31],[119,-427],[349,-214],[30,253],[207,-39],[183,37],[11,228],[62,-24],[66,179],[204,-55],[406,-2],[126,-176],[134,-86]],[[30340,48614],[-9,156],[57,501],[-91,75],[-56,446],[-71,322],[37,157],[-354,199],[-96,221],[191,187],[-28,378],[-46,16],[-83,572],[-149,-61],[-236,-350],[-181,47],[-21,-348],[-262,-272],[-30,-173],[-113,-105],[-59,-205],[-67,82],[-126,-126],[-456,-261],[18,352],[-195,-93],[-104,-280],[-146,-567],[-107,-197],[199,-439],[39,-216],[-296,-372],[40,-108],[-145,-203]],[[32783,41682],[-160,-307],[-11,164],[-103,349],[-124,174],[-157,109],[-191,216],[-540,340],[-1072,505],[33,366],[91,26],[-188,480],[-175,251],[9,499],[-43,308],[118,123],[7,426],[-65,92],[62,180],[-66,268],[20,323],[-78,13],[13,532],[-202,-36],[-19,526],[-70,7],[-28,586],[229,451],[18,-173],[249,134]],[[33724,30943],[105,313],[-60,54],[-216,-115],[11,328],[86,143],[-62,312],[-381,98],[-33,454],[-235,78],[-11,314],[-188,-93],[-44,392],[72,464],[-2,419],[-421,41],[47,494],[-138,7],[-32,174],[36,194],[-99,93],[9,308],[-149,-25],[-269,151],[70,669],[45,196],[237,-204],[68,236],[154,-99],[212,592],[-108,845],[167,284],[373,243],[551,151],[62,-428],[399,222],[112,-18],[-92,296],[249,250],[-196,576],[-429,1039],[-344,631],[-497,660]],[[28432,27348],[161,12],[173,-128],[185,0],[66,-159],[128,50],[261,-187],[217,24],[151,94],[-33,241],[-78,188],[96,49],[-34,313],[109,412],[72,117],[137,-291],[163,105],[99,351],[197,-287],[41,-262],[341,112],[10,-63],[-162,-477],[41,-149],[-113,-145],[146,-58],[228,132],[394,433],[46,-169],[252,140],[174,-28],[-57,-314],[74,-314],[142,40],[-127,-463],[119,-98],[99,90],[234,-74],[170,30],[194,-191],[77,10],[29,199],[-5,440],[-118,-9],[110,264],[-102,66],[85,318],[-107,133],[58,325],[133,-31],[199,-192],[90,47],[-114,297],[140,382],[-144,134],[96,168],[-71,74],[106,267],[-217,367],[73,191],[120,54],[61,254],[120,12],[200,-158],[89,285],[-55,310],[36,295],[87,17]],[[27394,47949],[54,-291],[234,-206],[71,62],[193,-53],[582,-354],[130,-501],[67,6],[-124,-814],[-81,-361],[-148,-345],[226,-488],[-59,-121],[43,-394],[-34,-150],[-24,-778],[81,-435],[78,-155],[-36,-165],[30,-927],[-63,-19],[-6,-300],[-75,-350],[104,-230],[-117,-342],[-103,-89],[-25,-287],[-168,-653],[-113,-30],[0,-965],[96,-31],[32,-992],[-70,-1852],[246,63],[245,-210],[32,-329],[80,-322],[9,-226],[-105,-169],[-303,-160],[-412,-316],[-285,-275],[-65,54],[-343,-258],[37,-320],[-128,-552],[58,-532],[-28,-151],[-345,-600],[-100,-60],[441,-310],[2,-462],[-145,-358],[86,-119],[-50,-197],[91,-146],[244,107],[99,-130],[432,-81],[33,-468],[142,-624],[211,-170],[-10,-92],[-207,-126],[17,-111],[257,-189],[27,-152]],[[30646,66441],[-5,-762],[203,-597],[81,-447],[449,-547],[-266,-415],[45,-220],[146,-1122],[86,-405],[97,-156],[-134,-225],[88,0],[94,-240],[227,78],[213,255],[57,-131],[79,-713],[-24,-491],[317,271],[165,-181],[124,-516],[76,291],[335,110],[208,22],[86,-63],[36,-293],[2,-398],[57,-135],[-24,-170],[192,-333],[60,-7]],[[30866,66587],[-220,-146]],[[34979,67477],[-1936,-599],[-357,-75],[-750,-41],[-529,-2],[-207,-36],[-334,-137]],[[36885,59245],[183,322],[-292,601],[-163,384],[-228,-243],[-146,181],[-110,383],[47,220],[-35,339],[-151,774],[-38,451],[-20,620],[-335,-190],[-36,795],[337,236],[-93,650],[-291,-213],[-270,1164],[302,205],[-186,839],[-302,-59],[-79,773]],[[33716,58901],[153,14],[149,-170],[196,115],[151,327],[219,-365],[258,238],[100,-48],[124,75],[23,249],[117,266],[84,-130],[29,-204],[299,-209],[191,131],[209,68],[343,307],[147,29],[162,-168],[42,-126],[173,-55]],[[24798,48524],[284,-19],[310,-109],[355,-193],[768,-712],[-43,187],[150,266],[260,313],[356,-485],[156,177]],[[22781,58934],[42,91],[140,969],[294,-67],[112,866],[1128,-494],[-115,-982],[-25,-1114],[268,33],[229,-716],[-59,-64],[18,-209],[85,26],[96,-447],[-133,-120],[562,113],[77,-714],[53,-267],[-379,-126],[-25,-237],[82,11],[-7,-185],[73,-15],[40,-287],[257,-342],[316,-146],[12,-327],[-63,-187],[80,-107],[-12,-460],[70,-123],[455,181],[31,-216],[-91,-412],[15,-146],[-265,-103],[-30,94],[-113,-127],[-405,-172],[-141,66],[-23,-464],[-185,26],[-58,-205],[-183,-44],[-19,-190],[162,-304],[-93,-301],[-42,-547],[36,-165],[267,-285],[144,-447],[-168,49],[-238,-297],[-79,-437],[-176,-337]],[[21264,61285],[-115,-826],[179,-35],[10,-965],[302,166],[51,156],[336,-84],[-64,-901],[810,153],[8,-15]],[[22652,63078],[-32,-42],[-599,88],[-31,-513],[-461,114],[-35,-627],[-180,-450],[159,-320],[-209,-43]],[[30646,66441],[-741,-491],[-1924,-1308],[-229,-147],[-265,-111],[-537,-176],[-372,-92],[-21,-245],[-1296,-349],[-998,-192],[6,-46],[-1084,-225],[-533,19]],[[33417,55426],[325,78],[-46,167],[149,256],[327,223],[258,375],[-121,260],[-104,625],[-114,308],[-158,-173],[-217,1356]],[[30340,48614],[6,-298],[189,94],[735,-98],[99,225],[253,-23],[148,-173],[94,180],[-104,245],[111,258],[-149,288],[186,479],[38,-37],[118,383],[164,294],[47,167],[54,889],[79,323],[-148,244],[-77,294],[50,25],[-2,662],[-44,5],[55,597],[197,529],[186,352],[-116,228],[319,482],[131,383],[161,9],[335,143],[-38,-337]],[[22781,58934],[-13,-59],[40,-805],[-426,-83],[-199,29],[-401,-158],[-135,-93],[-124,-211],[17,-289],[-63,-183],[-265,-202],[-689,147],[-363,-74],[32,-410],[-219,-107],[140,-536],[220,-684],[-113,-121],[121,-369],[36,-218],[87,26],[18,-263],[109,-99],[-80,-213],[23,-222],[127,-234],[-62,-193],[165,-309],[-47,-187],[99,-484],[224,-3],[111,-492],[182,-348],[-46,-257],[219,-8],[8,-286],[-74,-385],[166,56],[59,-160],[-66,-321],[73,-215],[-23,-800],[430,-257],[321,-138],[465,-56],[546,92],[79,41],[-19,-322],[222,94],[58,-113],[375,15],[392,55],[280,2]],[[43303,65237],[-1696,1186],[-2003,1184],[-499,220]],[[41294,58694],[89,176],[122,-52],[-3,-335],[80,-28],[274,122],[139,12],[135,154],[173,23],[59,241],[-19,390],[40,196],[128,267],[-82,466],[120,591],[-383,336],[87,290],[89,-18],[158,491],[-35,178],[146,198],[-133,224],[-27,167],[107,282],[257,-34],[109,363],[20,207],[199,-261],[143,230],[-34,51],[-112,649],[32,467],[60,-8],[71,508]],[[36885,59245],[221,-85],[222,-242],[324,265],[203,277],[396,112],[174,-4],[272,-100],[126,15],[411,332],[120,37],[-3,373],[-40,258],[26,498],[113,-125],[317,-119],[214,-195],[351,-74],[172,-225],[114,273],[67,-99],[-18,-255],[68,-477],[-100,-230],[357,13],[-73,-420],[86,36],[1,-368],[288,-22]],[[39105,67827],[-389,90],[-313,19],[-2470,-240],[-413,-60],[-541,-159]],[[32783,41682],[193,275],[337,407],[169,361],[132,506],[109,-46]],[[33768,51923],[73,168],[-166,368],[383,241],[-93,164],[188,163],[-198,807],[-139,66],[-204,219],[-233,120],[-1,336],[39,210],[-139,308],[139,333]],[[33723,43185],[89,100],[-154,444],[148,45],[264,184],[-115,137],[214,259],[451,376],[127,516],[-93,68],[-156,338],[-4,267],[-402,-262],[95,346],[-380,1559],[296,234],[-77,469],[114,-98],[435,-20],[106,634],[171,188],[-38,187],[-129,-62],[-122,482],[-164,402],[-5,214],[-59,-2],[-141,292],[-80,261],[-86,-30],[-121,761],[-172,-132],[-247,219],[31,125],[176,89],[73,148]],[[17677,69831],[-42,584],[-297,-45],[-182,53],[45,200],[-54,597],[-77,-5],[-102,458],[171,145],[-104,603],[-14,250],[-143,153]],[[16216,65501],[234,1474],[246,-134],[99,451],[-186,110],[143,281],[59,448],[111,387],[-46,688],[32,-107],[239,-74],[40,141],[193,-17],[5,155],[326,189],[-34,338]],[[16878,72824],[-117,-418],[-16,-478],[20,-224],[-101,-246],[-56,-276],[131,-462],[-2,-118],[-288,151],[-181,186],[-290,107],[-84,-59],[-271,23],[-100,70],[-498,206],[25,220],[-107,2],[14,408],[47,439],[188,513],[-61,307],[-248,-128],[9,164],[-135,-4],[-314,378],[-376,381],[-199,90],[-17,121],[-236,-19],[-151,54],[39,139],[-178,97],[13,211],[-140,47],[44,136],[-253,45],[-4,-188],[-353,201],[-357,449],[-329,249],[-228,219],[-116,43],[-290,-6],[-63,43],[-246,-563],[-136,125],[-24,231],[-156,230],[-362,376],[-126,260],[-45,293],[-175,484],[-205,-364],[-61,-238],[7,-431],[71,-568],[-31,-312],[-65,-130],[31,-1155],[-335,2],[-49,-357],[-98,83],[-62,-139],[-152,27],[-45,-1040],[-31,-149],[318,-212],[37,-267],[-44,-294],[31,-299],[161,-379],[9,-161],[157,-191],[236,-423],[-34,-181],[304,-87],[-91,-136],[-4,-326],[-53,-26],[-19,-266],[-190,-319],[-13,-114],[187,-144],[15,-229],[123,-886],[786,179],[433,44],[464,0],[408,-84],[281,-129],[3760,-2131]],[[33723,43185],[502,-442],[153,218],[220,-217],[216,229],[327,-404],[21,80],[262,-353],[320,140],[17,185],[182,11],[-53,346],[194,88],[47,242],[328,14],[-47,409],[421,-75],[379,-262],[341,-86],[-42,138],[238,2],[420,196]],[[38922,49056],[-169,272],[-228,12],[-569,264],[42,788],[-668,265],[-501,71],[7,97],[-169,25],[-25,196],[-291,-18],[-167,-106],[-41,272],[-312,-143],[-110,335],[-364,-285],[-67,26],[-93,685],[-157,154],[-82,-105],[-77,82],[-143,-119],[-1,117],[-349,-84],[-182,98],[-33,131],[-181,-110],[-18,-140],[-206,87]],[[38169,43644],[-42,506],[-230,-91],[-43,517],[-258,-40],[-43,795],[-156,82],[-23,1063],[105,81],[-8,273],[-213,5],[20,402],[253,931],[40,46],[146,-225],[278,19],[174,264],[75,22],[65,186],[93,37],[167,-117],[10,226],[61,68],[226,-60],[-27,155],[83,267]],[[42671,50576],[-11,185],[65,272],[56,609],[103,139],[-60,603],[-104,171],[-40,252],[-96,93]],[[38922,49056],[146,32],[57,-121],[453,348],[135,-132],[187,233],[79,342],[174,150],[44,154],[218,-113],[45,-163],[28,-445],[81,408],[130,-28],[176,71],[59,264],[96,127],[69,-400],[301,34],[139,433],[57,-303],[298,208],[65,-164],[206,157],[42,266],[216,191],[111,196],[137,-225]],[[42584,52900],[-180,220],[-77,389],[-354,-462],[-120,477],[49,352],[-104,107],[-225,-177],[-476,-4],[-313,-91],[-3,490],[513,270],[50,438],[69,33],[61,586],[121,169],[108,339],[33,543],[-106,620],[-165,268],[-69,232],[-69,574],[35,237],[-68,184]],[[24147,70130],[-304,26],[-150,82],[-381,388],[-60,550],[43,6],[-3,311],[-438,-118],[-10,108],[-242,-136],[-150,0],[1,122],[-130,185],[-298,136],[5,615],[46,224],[-155,-85],[-258,2],[-196,63],[-28,284],[-103,223],[5,460],[-114,417],[-175,150],[-148,17],[-119,-571],[-341,-478],[-214,-142],[-226,64],[-271,277],[-152,-110],[-11,-322],[109,-268],[-149,-562],[-232,115],[-33,-433],[-213,34],[-215,-944],[-155,59],[-56,111],[-117,-161],[-484,-181],[-36,-357],[55,-601],[-367,141]],[[22652,63078],[-10,287],[165,244],[-27,1231],[-22,407],[-144,12],[-29,697],[426,-166],[159,-1],[-14,273],[92,-99],[240,-51],[387,30],[90,146],[-291,272],[19,397],[212,232],[108,-9],[-63,152],[197,2998]],[[16216,65501],[990,-563],[-58,-318],[-376,214],[-43,-70],[-117,-678],[625,-298],[-108,-709],[44,-51],[-95,-668],[407,-201],[-75,-873],[784,-413],[347,4],[81,558],[293,-163],[42,309],[50,17],[195,-246],[54,461],[164,-177],[766,-414],[66,521],[75,209],[937,-667]],[[30140,68374],[-137,235],[61,96],[-40,176],[-289,338],[-120,-6],[-82,230],[-299,52],[-202,78],[-177,231],[-172,114],[-282,22],[-121,101],[-448,107],[-205,-23],[-190,-115],[-104,169],[-311,39],[-94,91]],[[30866,66587],[-19,286],[-188,622],[-153,-60],[-20,390],[-114,199],[-12,164],[-222,17],[2,169]],[[26928,70309],[52,-280],[-44,-31],[-10,-358],[-344,72],[-36,-200],[-470,106],[-111,104],[-928,309],[-228,185],[-55,-71],[-307,60],[-289,4],[-11,-79]],[[70343,76980],[-176,-334],[405,-530],[151,-378],[138,-163],[-97,-175],[278,-573],[182,-502],[-281,-450],[167,-358],[643,-1199],[750,-1537],[68,-85],[-334,-513],[375,-718],[96,-741],[-122,-121],[17,-257],[-59,-58],[66,-216],[2,-419],[217,116],[22,-59],[262,170]],[[73275,79795],[-160,-427],[-335,-769],[-442,-721],[-160,331],[-282,-421],[-309,361],[-239,-418],[-268,384],[-220,-321],[-141,195],[-305,-866],[-71,-143]],[[75335,77935],[-181,218],[-73,198],[-65,-14],[-144,213],[-293,263],[-277,138],[-253,249],[-161,285],[-32,141],[-214,296],[-92,-341],[-275,214]],[[73113,67880],[25,265],[158,289],[318,140],[194,282],[130,474],[-102,95],[134,239],[-101,256],[85,186],[37,256],[336,406],[-25,230],[306,-291],[176,489],[-229,287],[108,244],[-398,597],[69,228],[-84,291],[221,692],[-168,178],[205,653],[-92,48],[273,472],[-207,259],[245,438],[-299,438],[279,477],[-122,309],[174,50],[249,520],[59,-65],[268,623]],[[67719,84440],[-90,57],[-227,338],[-261,213],[-151,350],[-41,311],[-57,37],[-170,450],[-247,20],[-257,-334],[-209,88]],[[66895,78875],[52,254],[143,324],[-50,79],[155,196],[155,-109],[168,147],[177,376],[-79,204],[210,638],[-480,502],[182,561],[174,-182],[152,391],[-289,552],[-320,334],[135,391],[33,305],[150,189],[81,307],[75,106]],[[65141,81916],[-49,-592],[12,-195],[98,-307],[-57,-100],[187,-342],[72,-331],[52,18],[45,522],[131,138],[174,391],[376,-452],[161,-134],[-64,-188],[-1,-232],[157,-349],[95,212],[179,-150],[-86,-220],[222,-289],[-34,-271],[84,-170]],[[66009,85970],[-87,-853],[-99,-613],[90,20],[-39,-496],[-50,-187],[-153,49],[-36,-356],[53,-12],[-88,-637],[-153,-501],[-87,-90],[-219,-378]],[[55585,91735],[3,74],[-611,69],[-2,384]],[[53850,82809],[144,471],[34,498],[-113,452],[-7,772],[81,313],[182,353],[130,482],[122,91],[185,751],[-54,373],[-233,118],[-97,322],[22,343],[-57,367],[473,113],[187,-25],[-134,152],[95,410],[-29,24],[124,534],[164,-109],[53,282],[79,-9],[156,604],[158,-34],[68,739],[2,539]],[[49934,84776],[304,93],[31,68],[237,-145],[117,-388],[363,-318],[402,111],[136,-97],[90,-192],[143,-39],[168,-252],[157,228],[170,137],[120,-123],[72,-256],[119,-181],[52,190],[269,-257],[161,-248],[66,-13],[219,316],[176,-72],[175,-199],[169,-330]],[[49547,85544],[119,-269],[268,-499]],[[48703,94767],[-53,-303],[-189,-614],[-130,-336],[-113,-409],[184,-400],[157,-255],[451,-425],[44,74],[194,-248],[184,-303],[63,70],[131,-401],[97,-124],[-45,-161],[-299,-113],[-81,-127],[65,-303],[-20,-149],[791,-397],[-73,-293],[130,-379],[-40,-370],[88,-336],[-100,-285],[115,-357],[-79,-343],[-72,-85],[-151,-518],[-130,-150],[-153,-57],[-158,-187],[-24,-109],[138,-180],[99,-321],[-177,-329]],[[54975,92262],[-140,-66],[-254,127],[-372,71],[-204,1],[-398,-249],[-197,-14],[-9,135],[-421,224],[-289,-189],[-201,34],[-134,161],[-248,451],[-229,607],[-22,414],[-254,702],[-182,-18],[-304,152],[28,395],[-64,-249],[-150,-3],[-178,-93],[-102,-162],[17,-129],[-127,-438],[-211,-184],[-54,-133],[-169,-142],[-229,71],[-452,553],[-247,544],[-218,47],[-108,-136],[-150,21]],[[57655,91651],[-115,176],[-205,170],[-465,275],[-308,69],[-357,211],[-201,17],[-406,-269],[-200,-13],[-154,88],[-17,-236],[-213,-25],[-39,148]],[[55585,91735],[153,-22],[1030,17],[159,-37],[295,-239],[149,175],[47,-122],[326,-104],[-89,248]],[[73113,67880],[44,-154],[80,-566],[-222,-400],[-182,-469],[131,-266],[250,724],[129,147],[127,-236],[-157,-275],[68,-199],[-12,-244],[-64,-35],[-68,-232],[241,-417],[198,147],[49,954],[406,-133],[246,69],[145,-326],[259,-92]],[[79421,72868],[-35,1],[-280,479],[-389,471],[-70,242],[-136,236],[-167,569],[-113,73],[-172,331],[-173,65],[-245,512],[-313,256],[-50,253],[-122,49],[-181,-55],[-212,348],[-151,122],[-149,12],[-218,193],[-130,272],[-180,273],[-239,183],[-192,15],[-169,167]],[[55038,78870],[5,-119],[302,-10],[33,-96],[-496,-731],[-442,-715],[-304,-443],[77,-95],[48,-250],[-174,-492],[-271,-235],[-48,-479],[-131,-191],[-77,-222],[13,-246],[-98,-242],[-122,-52],[-158,-244]],[[57991,82161],[-262,-50],[-493,-227],[-863,266],[-107,-150],[-173,-95],[-206,-11],[-232,-271],[-91,-233],[-77,-384],[43,-439],[-43,-527],[-59,-285],[-144,-423],[-161,-9],[-37,-430],[-48,-23]],[[62153,78728],[242,182],[-150,166],[72,410],[130,532],[-98,142],[-132,337],[26,149],[-181,164],[-172,60],[99,588],[90,27],[67,323],[-544,324],[94,530],[-176,169],[-8,-162],[-381,341],[-53,-636],[-279,22],[-106,-492],[73,-48],[5,-427],[-137,-448],[-48,-283],[-206,-636],[-82,-184],[169,-220],[433,-185],[-22,-441],[72,8],[96,-325],[-19,-111],[-326,-53],[-321,146],[-443,76],[80,302],[-175,193],[-25,127],[-547,679],[-478,654],[-119,43],[-29,261],[-171,200],[-22,269],[-285,-12],[-168,473],[-7,199]],[[63482,73915],[52,309],[-81,41],[29,875],[-84,26],[40,615],[-193,-5],[-245,243],[-44,131],[-101,712],[-69,255],[81,192],[-829,1018],[115,401]],[[58703,67444],[157,657],[220,-93],[49,47],[-12,583],[22,285],[157,-54],[1262,-761],[130,-38],[60,290],[109,274],[130,471],[404,-408],[84,-240],[406,183],[1,-175],[134,81],[82,-144],[422,729],[-72,586],[-7,890],[-19,11],[-6,750],[274,-12],[33,270],[155,196],[77,566],[97,471],[151,550],[96,473],[183,33]],[[54557,67022],[77,-58],[91,-460],[112,-151],[32,99],[203,134],[252,-44],[301,145],[293,-82],[216,-2],[22,-331],[151,78],[360,304],[267,91],[207,-17],[129,148],[1,666],[201,-13],[34,254],[195,-207],[527,-139],[35,238],[301,-65],[139,-166]],[[53228,72957],[54,-275],[96,-200],[-121,-400],[66,-321],[-100,-408],[-27,-263],[-137,-79],[144,-949],[-84,-119],[4,-407],[283,115],[54,149],[560,73],[73,-326],[385,35],[54,-255],[10,-475],[-74,-350],[-56,-21],[-182,-412],[-72,-574],[38,-139],[148,-84],[213,-250]],[[53195,74008],[35,-226],[165,-170],[158,-370],[-117,-73],[1,-258],[-209,46]],[[62153,78728],[377,-239],[507,24],[132,-73],[157,389],[-237,164],[95,272],[138,566],[18,204],[109,-39],[60,187],[-35,194],[157,276],[-134,355],[119,216],[160,169],[43,353],[283,-109],[159,-114],[56,230],[212,-237],[167,826],[445,-426]],[[60754,90822],[-271,-582],[190,-160],[-69,-240],[-146,-236],[-120,72],[-137,-242],[144,-413],[76,-41],[-10,-593],[-76,-433],[-106,13],[-88,-373],[-77,14],[-5,-222],[-63,-202],[-194,120],[-111,-196],[-200,202],[-19,-378],[-163,-525],[-229,22],[-94,-258],[52,-23],[-72,-971],[-221,-619],[-194,119],[-71,-497],[77,-51],[-35,-342],[-223,-574],[-33,-282],[-107,-219],[-73,-322],[-95,-229]],[[66009,85970],[-182,325],[-250,269],[-230,127],[-104,197],[-150,111],[-211,-34],[-131,291],[-107,96],[-90,-58],[-103,120],[-218,29],[-14,-434],[-109,63],[106,401],[-270,139],[-171,319],[-459,976],[-96,133],[-61,-304],[86,-180],[-107,-80],[-176,115],[197,551],[-151,390],[-474,-367],[-238,-273],[-58,555],[-258,-134],[-169,9],[-165,-199],[-114,376],[-493,821],[-285,502]],[[67442,69869],[9,-546],[184,266],[126,310],[159,139],[215,4],[74,-580],[99,-94],[249,152],[111,-268],[155,-14],[29,-148],[283,195],[201,-129],[283,-326],[-32,-458],[127,-422],[-13,-397],[-139,-606],[111,-110],[110,-232],[-82,-152],[516,-1186],[-26,-41],[144,-708],[550,253],[71,145],[84,-462],[128,-424],[-199,-176],[252,-902]],[[67690,77332],[-138,-374],[-187,-20],[-36,-245],[50,-220],[102,-125],[-125,-1045],[63,-111],[159,-49],[235,-334],[105,8],[-155,-423],[160,-331],[-90,-496],[132,112],[146,-668],[-11,-266],[-133,-144],[-171,113],[16,-303],[-71,-244],[498,-832],[-133,-242],[-152,-33],[-195,-442],[-329,-167],[74,-415],[-62,-167]],[[70343,76980],[-213,380],[-33,-18],[-321,738],[-118,-333],[-117,-106],[-221,424],[-299,342],[-129,-246],[-179,-225],[67,-180],[-109,-192],[-124,-15],[-223,319],[32,-106],[-110,-298],[-66,-517],[-490,385]],[[63482,73915],[166,-48],[133,72],[112,-122],[-183,-538],[205,-22],[53,-316],[381,-90],[158,-430],[136,-180],[97,-299],[99,201],[7,280],[267,-8],[-12,149],[373,-453],[273,-395],[209,-390],[-186,-279],[112,-201],[-22,-206],[39,-237]],[[67690,77332],[-461,410],[52,307],[103,362],[-165,341],[-24,-80],[-146,86],[-36,-66],[-118,183]],[[65899,70403],[42,-158],[146,-893],[212,-18],[13,501],[119,27],[168,-363],[256,392],[56,-65],[23,-274],[200,192],[70,-41],[238,166]],[[73275,79795],[-785,593],[-227,286],[-110,214],[-342,201],[-442,749],[-224,241],[-243,130],[-119,158],[-306,82],[-84,116],[-186,-25],[-242,-132],[-261,108],[-252,230],[-80,241],[42,167],[-91,173],[-133,97],[-128,-339],[-274,-56],[-551,546],[-129,190],[10,210],[-294,70],[-105,395]],[[60754,90822],[-360,603],[-81,183],[2,202],[-280,711],[-142,91],[-128,-152],[-358,-68],[-404,303],[-188,-13],[-399,-597],[-362,-391],[-269,-119],[-130,76]],[[53850,82809],[-46,-126],[170,-380],[128,-517],[148,-1026],[-9,-160],[85,-401],[-34,-344],[68,-261],[130,-124],[146,-409],[172,-36],[117,-176],[113,21]],[[47437,78578],[64,-192],[-179,-263],[-125,-38],[-288,-384],[-14,-280],[15,-618],[51,-332],[-180,-153],[-70,72],[-104,-184],[25,-94],[-181,-254],[118,-133],[4,-157],[89,2],[67,-816],[223,46],[-10,-212],[293,167],[883,378],[736,196],[836,100],[960,0],[354,-101],[518,-59],[283,30],[-55,-137],[814,153],[16,67],[225,90],[-14,-154],[202,-25],[-22,-163],[68,-86],[-31,-288],[-143,-192],[-3,-203],[90,-127],[166,-82],[77,-144]],[[49934,84776],[-139,-239],[-81,-841],[117,-491],[-366,-133],[60,-536],[-332,-114],[-238,-25],[-268,-161],[17,-231],[-393,-365],[13,223],[-117,344],[-156,178],[-297,-150],[267,-895],[-60,-94],[-114,-421],[66,-180],[255,132],[78,-344],[-102,-18],[-84,-230],[-2,-243],[-185,-126],[77,-373],[-210,-317],[43,-151],[-227,-305],[-119,-92]],[[43202,43658],[56,58],[443,733],[462,471],[135,-110],[171,460],[85,620],[207,166],[78,278],[323,398],[39,-61],[357,241],[65,-49],[-38,-166],[168,131],[-31,-151],[248,173],[55,-32],[341,206],[559,474],[149,-631],[171,76],[-97,-416],[8,-116],[438,359],[204,-564],[323,252],[-95,232],[292,194],[138,-311],[282,-199],[184,-366],[203,-159],[359,335]],[[42671,50576],[18,-320],[-180,-163],[-131,-418],[104,-628],[-404,-471],[126,-325],[96,101],[139,-373],[240,204],[129,-473],[-72,-326],[167,-532],[91,-456],[-343,-278],[348,-899],[-56,-137],[158,-354],[-15,-396],[87,-151],[46,-223],[-102,-81],[85,-219]],[[46529,55166],[-102,84],[-227,-53],[-4,221],[-161,-53],[-178,59],[-351,-178],[-274,-344],[-122,-358],[-203,-184],[-279,-358],[-159,-34],[-124,122],[-112,302],[-176,111],[-66,118],[-292,-327],[21,-100],[-306,-334],[-95,125],[-262,-465],[-191,-391],[-162,-78],[-120,-151]],[[51636,45480],[198,-29],[-86,207],[-99,-1],[0,394],[-89,28],[-174,-103],[48,350],[-9,542],[-153,118],[1,923],[-51,229],[86,38],[-18,172],[289,322],[21,-187],[151,-101],[-57,886],[-9,561],[-138,41],[-70,467],[-202,-17],[-22,102],[-291,73],[143,84],[-40,874],[-109,397],[-164,-103],[-8,134],[-275,-306],[104,373],[-22,462],[-282,1154],[-81,250],[-317,722],[-460,-268],[20,-291],[-204,-86],[-270,-24],[76,-583],[-256,-18],[-122,176],[-648,-213],[-17,174],[-123,-48],[-34,244],[-547,-97],[33,-314],[-444,-284],[-53,469],[-348,-258],[-39,47],[-114,-319],[-274,727],[147,99],[-62,203],[225,942],[132,352]],[[49484,46184],[-11,156],[594,-63],[326,0],[7,-213],[397,134],[11,-300],[55,-246],[206,-242],[377,-83],[20,169],[170,-16]],[[46488,38293],[-144,285],[-124,812],[133,118],[-78,262],[-69,57],[-444,-137],[-114,120],[-18,-107],[-438,585],[-446,-285],[-96,221],[-178,25],[-207,327],[-187,-418],[-5,101],[-200,-219],[-42,257],[-55,-22],[-155,-292],[-115,176],[-127,-256],[-205,271],[-165,150],[-300,-586],[-271,500],[167,297],[-105,423],[-183,27],[246,245]],[[42837,36190],[34,136],[243,-106],[99,119],[268,49],[81,-240],[184,-123],[92,-199],[116,200],[351,25],[147,134],[113,233],[141,-174],[115,-261],[220,373],[3,185],[601,584],[115,-235],[71,132],[-31,162],[164,292],[401,476],[-99,324],[222,17]],[[40860,38639],[151,-102],[302,76],[87,411],[34,-77],[116,365],[214,223],[427,-186],[166,-348],[-47,-88],[291,-427],[-112,-141],[132,-455],[-66,-149],[135,-630],[32,-537],[-21,-364],[136,-20]],[[40337,40149],[202,-345],[22,-219],[195,-88],[62,-355],[42,-503]],[[42563,41230],[-140,333],[-37,184],[-190,-26],[-73,-121],[-86,128],[-56,-154],[-178,71],[42,95],[-73,230],[-214,-17],[-127,-163],[66,-43],[-414,-746],[-410,-270],[-83,-363],[-232,-114],[-21,-105]],[[35098,22684],[125,165],[-28,280],[-159,361],[-191,173],[-114,-135],[-51,61],[61,197],[236,-13],[104,167],[19,215],[68,-89],[101,151],[56,223],[-364,226],[-138,20],[42,261],[228,227],[-82,142],[192,342],[-209,355],[200,280],[-65,898],[113,-28],[23,449],[89,-34],[91,607],[-75,11],[-88,525],[-189,-99],[-132,581]],[[33032,17591],[7,-158],[109,37],[271,-95],[181,267],[154,-171],[47,273],[144,158],[106,-27],[109,-181],[373,-237],[202,-284],[119,121],[226,25],[144,-96],[207,126],[-32,303],[-249,10],[-165,155],[-133,15],[231,226],[83,452],[155,-26],[-41,495],[279,111],[46,108],[8,655],[70,10],[-111,273],[-133,-247],[-139,-2],[-26,438],[-150,34],[-158,-80],[-17,306],[-58,155],[-351,289],[91,203],[46,311],[191,307],[-21,308],[251,526]],[[28432,27348],[168,-110],[94,-624],[-110,-280],[47,-160],[306,-333],[-39,-123],[172,-623],[140,-410],[-8,-91],[174,-64],[231,-194],[204,-412],[66,-271],[140,-113],[85,-375],[170,-424],[23,-192],[-183,-134],[-170,-196],[-62,16],[-140,-494],[-203,-268],[24,-203],[334,-685],[6,-226],[182,-399],[-24,-244],[542,-673],[307,4],[91,54],[225,-93],[144,45],[176,-87],[145,-269],[208,-158],[362,61],[96,-65],[197,196],[257,18],[227,-38],[221,84],[-70,-220],[120,-194],[-162,-295],[-113,-495]],[[34961,29203],[-72,-183],[-147,253],[-155,47],[10,528],[-172,150],[-52,229],[-170,72],[-193,-316],[-148,110],[68,591],[-19,233],[-187,26]],[[31598,17857],[-132,-113],[-135,237],[-259,-267],[-152,-263],[-131,401],[-42,295],[-148,-2],[-157,-243],[-120,-372],[-123,-167],[-6,-331],[118,-213],[461,-313],[94,-117]],[[30866,16389],[223,504],[145,251],[77,20],[62,-202],[118,163],[-69,246],[281,331],[-105,155]],[[53128,42870],[-156,197],[109,438],[10,519],[-118,149],[48,229],[-60,164],[-54,-70],[-137,477],[-95,201],[-39,-132],[-251,210],[-403,-25],[62,-118],[-87,-165],[-48,158],[-121,-14],[-44,304],[-108,88]],[[53121,42074],[-128,37],[-70,136],[9,240],[196,383]],[[51387,38263],[5,109],[147,170],[168,332],[62,250],[175,452],[113,153],[217,108],[241,368],[221,117],[-34,210],[290,295],[19,172],[157,394],[-72,333],[25,348]],[[46488,38293],[40,-350],[46,7],[187,-594],[184,174],[141,-123],[88,-345],[63,57],[190,-45],[181,117],[-127,-179],[146,-30],[45,-514],[71,-96],[236,50],[110,-275],[118,-441],[246,129],[137,123],[62,195],[-97,229],[-30,204],[103,130],[62,215],[114,-165],[25,132],[103,-11],[64,408],[58,35],[141,-269],[94,28],[-50,-273],[143,105],[71,146],[155,-59],[188,86],[266,398],[37,-88],[174,337],[208,-407],[208,147],[129,302],[299,269],[-11,119],[281,92]],[[49484,46184],[134,-67],[-103,-190],[74,-60],[101,-377],[273,-487],[19,-228],[-148,-52],[253,-522],[19,-275],[-104,-118],[132,-300],[151,-154],[168,-55],[99,-113],[65,-230],[-92,-198],[-212,-67],[-117,-267],[-90,-33],[-5,247],[-223,82],[2,196],[-519,60],[-188,239],[-183,38],[-29,155],[-123,226],[-32,471],[-174,177],[-268,-117],[-95,59],[-315,-86],[81,-472],[-190,-286],[-121,320],[-795,-446],[-304,-240],[-279,71],[251,-728],[48,-680],[-52,-33],[104,-463],[-119,-239],[-112,4],[112,-483],[-10,-102],[139,-113],[130,-321],[204,-324],[-39,-83],[130,-213],[-27,-139],[-150,54],[-139,-201],[-257,-238],[5,-400],[-76,-90]],[[39457,29428],[-13,275],[-56,5],[-30,238],[-137,-201],[-187,121],[-32,-204],[-120,86],[-36,-142],[-150,100],[-162,229],[-327,11],[-157,-230],[-95,-45],[-203,85],[-176,-109],[-85,-242],[-272,241],[-303,432],[-64,25],[59,377],[-105,241]],[[38626,22941],[-44,512],[-199,-31],[-29,111],[217,846],[-270,261],[-362,303],[-105,363],[52,157],[-126,402],[357,201],[-38,327],[132,271],[137,-263],[203,296],[79,-239],[221,268],[233,190],[313,-348],[129,343],[-192,233],[-262,131],[-61,414],[24,363],[78,414],[11,254],[119,195],[214,513]],[[35098,22684],[162,-172],[-139,-417],[26,-228],[64,-71],[8,-230],[242,103],[14,-54],[352,121],[263,-36],[86,-126],[184,-52],[21,-162],[58,149],[-44,182],[123,-50],[158,115],[129,3],[121,-722],[44,245],[195,324],[34,-109],[199,-84],[164,-143],[-61,387],[-87,795],[130,-97],[88,254],[194,-182],[-36,-155],[178,-96],[293,274],[169,-86],[169,58],[-40,139],[67,380]],[[36806,30721],[-64,-130],[-115,175],[-96,-148],[-261,-164],[-54,55],[-65,-417],[-187,210],[-93,-322],[-164,-74],[-218,100],[-254,290],[-145,-81],[39,-185],[-55,-137],[102,-235],[-99,-209],[-110,-56],[-6,-190]],[[33032,17591],[-92,-57],[-108,153],[-77,-184],[-328,-7],[-153,216],[-316,234],[-285,-4],[-75,-85]],[[41434,18931],[-230,523],[-69,672],[-118,62],[-77,420],[-98,365],[19,188],[169,26],[58,85],[-191,278],[-130,63],[-180,-97],[-109,19],[-212,-571],[-133,8],[-29,178],[-220,56],[1,-223],[-120,85],[-46,305],[27,301],[-223,159],[97,304],[-363,694],[-211,144],[-70,165],[-145,-142],[-205,-57]],[[30866,16389],[190,-138],[18,-225],[-85,-47],[-201,-327],[-78,-197],[20,-384],[-86,-146],[72,-481],[101,-284],[92,-620],[69,-125],[15,-215],[-133,-412],[-41,-390],[61,-242],[-10,-614],[-230,-305],[-151,-534],[-3,-350],[-256,-549],[-95,-139],[-87,-308],[-153,-382],[-10,-619],[-113,-260],[463,-321],[284,108],[156,-51],[72,92],[120,-153],[132,94],[15,-244],[122,-52],[769,-212],[189,-258],[143,-118],[135,-246],[197,-200],[60,-190],[108,-112],[-27,-194],[78,-283],[294,-380],[-2,-127],[135,-170],[89,-210],[292,-277],[158,-27],[104,-101],[241,-461],[412,-409],[118,-323],[135,-225],[7,-558],[-118,-383],[-114,-181],[-167,-604],[-11,-121],[129,-512],[77,-111],[227,-576],[157,709],[88,-16],[161,134],[34,235],[173,208],[214,45],[181,168],[237,132],[139,191],[-53,127],[63,269],[141,356],[84,305],[58,517],[309,-125],[188,-217],[144,216],[172,-3],[121,-342],[165,278],[9,290],[-30,558],[104,360],[35,304],[72,255],[88,96],[192,-104],[142,27],[29,130],[-17,368],[93,469],[91,259],[55,578],[98,448],[141,308],[-77,413],[-53,24],[-99,549],[-100,76],[-107,308],[-16,191],[83,342],[173,125],[54,487],[53,152],[-31,151],[105,333],[119,82],[-86,98],[50,255],[317,150],[-44,250],[42,61],[226,6],[100,124],[189,-324],[171,-73],[92,98],[198,-63],[203,8],[-22,153],[83,416],[68,-39],[72,291],[-128,130],[139,510],[47,545],[-6,203],[110,725],[-98,121],[95,272],[91,29],[16,202],[149,-78],[-74,227],[-285,155],[56,216],[-273,255],[92,140],[113,360],[-135,192],[87,307],[-117,82],[15,261],[-142,85],[-131,-88],[-43,150],[188,77],[155,-42],[16,212],[173,-79],[30,-155],[276,57],[-11,199],[129,46],[238,251],[322,255],[-179,536],[14,350],[70,46]],[[38169,43644],[17,8],[66,-797],[204,128],[73,-549],[-21,-314],[44,-20],[328,265],[124,-409],[235,309],[120,-178],[-40,-70],[91,-192],[40,-467],[208,21],[45,-237],[-28,-263],[102,-293],[215,-376],[103,7],[118,-115],[124,47]],[[42563,41230],[62,492],[-55,612],[-137,254],[309,431],[-13,65],[473,574]],[[40860,38639],[2,-121],[-117,-36],[-98,170],[-104,-91],[-87,-297],[-110,-144],[-55,-570],[-36,-46],[319,-320],[-136,-357],[-378,199],[-187,59],[-287,-6],[15,-276],[-194,-103],[151,14],[52,-226],[-144,-68],[-160,-314],[-72,-326],[34,-160],[-79,-71],[-202,-349],[-203,-447],[-11,-267],[43,-160],[-112,-166],[6,-341],[52,-35],[-135,-354],[-43,27],[-487,659],[-60,275],[-318,-372],[-68,-234],[-286,330],[-51,-352],[-163,-227],[163,0],[145,-193],[-203,-276],[-40,-282],[191,-182],[-51,-280],[12,-354],[-210,-108],[-11,-500],[-148,21],[34,-313],[-29,-111],[-198,-237]],[[44828,27205],[390,296],[-177,223],[-91,287],[-34,592],[131,431],[-452,413],[-492,287],[-541,192],[-905,581],[-246,238],[109,364],[342,593],[-184,-30],[-216,158],[26,448],[-33,803],[-188,-94],[-149,210],[23,218],[-321,22],[-10,77],[371,479],[-25,262],[34,222],[169,-168],[320,585],[3,266],[91,177],[-173,275],[59,249],[178,329]],[[39457,29428],[242,1565],[225,-195],[427,-243],[480,-145],[40,432],[285,-376],[93,-24],[793,23],[311,-11],[608,-238],[429,-312],[361,-412],[452,-690],[377,-885],[135,-453],[113,-259]],[[46835,25046],[-26,-211],[-172,6],[-59,-96],[-14,-303],[-115,-454],[-92,-167],[-125,-44],[-270,-1052],[395,-272],[-130,-147],[-206,-443],[114,-42],[299,41],[122,98],[20,-582],[-226,171],[-79,-6],[-83,-295],[11,-142]],[[46199,21106],[123,-55],[156,-177],[268,-155],[74,36],[102,247],[21,239],[135,-22],[-12,-333],[137,322],[-148,389],[34,61],[234,-42],[17,410],[690,-504],[-154,520],[134,-105],[122,-202],[122,80],[286,-146],[218,76],[-26,311],[-219,454],[249,151],[97,-59],[-26,-130],[125,-73],[231,329],[-467,315],[-103,217],[-418,154],[-40,647],[-162,176],[-323,524],[-96,62],[-245,-18],[-10,162],[-490,79]],[[53121,42074],[1,90],[156,86],[219,-506],[131,169],[-42,404],[77,10],[143,313],[144,170],[79,207],[159,9],[113,-82],[187,570],[141,213],[27,156],[188,103],[31,-153],[213,-34],[67,-98],[96,64],[301,-238],[95,-346],[136,-289],[33,-358],[-70,-278],[-38,39],[-129,-246],[-147,-175],[-12,-152],[-320,-446],[117,-76],[108,177],[97,-122],[-82,-173],[150,-232],[103,241],[290,380],[64,-100],[277,145],[402,298],[-8,325],[187,358],[83,-27],[89,151],[105,-40],[63,-336],[48,-54],[11,-622],[53,-191],[115,-111],[150,-263],[101,-50],[253,-515],[83,-67],[32,-189],[-79,-169],[-17,-322],[-130,-208],[157,-912],[76,42],[236,-442],[142,250],[155,-147],[133,278],[66,-406],[66,490],[64,-26],[90,181],[202,-300],[122,524],[102,109],[-62,69],[170,299],[0,133],[113,80],[109,378],[21,431],[251,185]],[[58615,50676],[-395,-372],[12,-253],[224,9],[78,-763],[-243,167],[-87,-988],[-143,21],[-30,-236],[-243,165],[-59,-179],[-126,46],[-141,-505],[49,-70],[-40,-291],[-335,-33],[-38,159],[-162,4],[-33,-158],[-98,-19],[9,-358],[-213,117],[-30,634],[-99,-54],[-154,-224],[97,413],[-104,107],[-353,-22],[-468,381],[-322,58],[-70,125],[-267,-14],[-38,-109],[-130,0],[-104,-290],[-140,-90],[-113,-210],[-79,-36],[-110,111],[-47,-118],[-195,18],[-284,250],[-153,-257],[299,-356],[-64,-506],[-129,16],[4,-406],[-55,-580],[216,-92],[-11,-273],[246,-12],[-103,-153],[13,-168],[-205,22],[43,-908],[96,-70],[1,-160],[88,10],[-33,-249],[61,-145],[11,-527],[-221,-266],[35,-176],[-92,-45],[-372,125],[-138,-23]],[[60582,50591],[-279,-121],[23,-376],[-479,-33],[-528,-116],[-4,-209],[-520,-38],[-5,585],[-112,323],[-63,70]],[[44802,26205],[26,332],[-135,425],[190,128],[-55,115]],[[44237,21108],[47,131],[-265,445],[105,490],[48,-64],[107,356],[347,-314],[80,-148],[121,351],[-95,144],[-149,54],[116,386],[75,-86],[125,172],[-36,154],[-359,341],[137,590],[-158,132],[3,942],[98,13],[86,173],[232,-164],[18,239],[-273,129],[66,787],[89,-156]],[[41434,18931],[65,-124],[205,24],[240,-237],[149,257],[115,-203],[212,135],[121,-54],[111,80],[126,227],[113,-380],[9,-217],[115,30],[169,258],[51,340],[55,-56],[351,442],[194,90],[75,718],[95,263],[-71,147],[188,202],[14,190],[101,45]],[[44237,21108],[97,-160],[304,-651],[-2,-109],[148,-466],[159,-45],[329,194],[143,-2],[135,340],[14,319],[212,-181],[51,51],[228,-527],[-37,-173],[-149,-104],[-196,-265],[45,-127],[353,278],[171,261],[33,321],[-251,423],[156,23],[40,160],[-21,438]],[[46835,25046],[-240,57],[-416,197],[-319,229],[-39,-124],[-226,311],[-719,415],[-74,74]],[[51387,38263],[52,33],[7,-426],[144,-34],[21,-394],[117,-136],[-99,-321],[111,-77],[53,-179],[-46,-254],[-132,-132],[345,-220],[-7,-84],[256,-669],[20,-422],[194,-562],[124,26],[67,188],[235,-8],[186,165],[338,24],[4,254],[89,291],[109,-118],[434,-137],[112,-128],[319,155],[82,-128],[230,4],[32,-117],[139,31],[-1,155],[123,-170],[183,142],[-44,-393],[242,-65],[-50,-219],[79,-14],[191,-655],[-13,-119],[261,2],[216,78],[342,248],[232,340],[-97,373],[20,232],[141,25],[23,140],[92,-57],[101,81],[299,108],[107,115],[124,-1],[42,204],[85,-151],[319,125],[91,-110],[46,202],[145,57],[93,-161],[203,-5],[-33,-149],[111,-102],[136,128],[82,-129],[163,330],[342,296],[16,91],[207,38],[112,125],[277,136],[50,-92],[148,142],[73,-200],[117,186],[107,23],[137,324],[188,169],[80,241],[-64,58],[68,454],[90,333],[150,303],[-35,132],[123,538],[146,414],[-108,289],[-169,272],[17,411],[186,143],[16,225],[219,303],[195,647]],[[41175,93583],[97,-539],[88,-734],[268,103],[421,82],[268,-32],[-13,-275],[91,-54],[85,-202],[231,-119],[44,-215],[204,-82],[4,-182],[-121,-153],[348,-65],[269,-192],[318,-349],[60,-275],[123,-46],[185,-201],[63,-191],[37,-430],[82,-362],[300,-89],[60,-142]],[[46058,94286],[-243,13],[-203,188],[-137,246],[-250,142],[-150,-212],[-188,-172],[-468,-133],[-213,-163],[-344,-66],[-213,121],[-195,200],[-16,179],[-188,246],[-129,27],[-292,-82],[8,122],[-267,-237],[-25,-246],[-99,-266],[-220,-225],[-203,7],[-180,-119],[-224,-36],[-444,-237]],[[45723,88481],[31,224],[-38,166],[92,262],[50,328],[-95,181],[-83,1047],[31,420],[-75,129],[89,315],[191,154],[-253,565],[-97,95],[-56,346],[5,250],[-89,170],[-129,84],[-218,452],[168,128],[398,15],[24,-573],[136,-85],[83,266],[77,-71],[128,157],[-78,232],[43,548]],[[44687,88839],[156,-114],[-11,94],[178,-70],[484,-80],[229,-188]],[[21022,81364],[58,-194],[264,-1443],[135,-31],[179,314],[168,-88],[-46,-519],[57,-230],[186,-115],[94,-181],[166,71],[274,32],[26,-224],[426,83],[801,-245],[-44,-288],[74,-338],[474,-256],[122,-243],[439,-588],[402,-162],[540,-169],[428,-180],[205,-209],[105,-231],[190,-9],[199,488],[482,371],[367,185],[89,118],[89,275],[317,284],[-47,319],[145,40],[-234,117],[61,35],[-90,520],[-75,93],[218,258],[233,413]],[[22578,86629],[-85,-286],[-129,-209],[-25,-172],[-211,-459],[61,-52],[-83,-207],[188,-380],[25,-332],[143,-524],[11,-373],[62,-656],[-41,-359],[61,-331],[-78,-315],[-183,-100],[-536,209],[-143,-223],[-593,-496]],[[27942,84578],[-131,18],[-208,-91],[-120,81],[-125,283],[-397,683],[-107,107],[-144,299],[-66,286],[-143,328],[-54,466],[-155,172],[-681,380],[-100,-49],[-28,-178],[-187,-313],[2,-108],[-236,23],[-56,-96],[-160,7],[-115,292],[24,266],[-69,134],[-246,-125],[-165,6],[-341,385],[-165,-166],[-236,-667],[32,-47],[-212,-669],[-770,325],[-5,19]],[[28499,79437],[-196,479],[-199,226],[-44,464],[54,98],[-188,198],[137,299],[110,373],[-138,318],[24,222],[-156,-80],[110,907],[-99,685],[39,220],[-42,337],[31,395]],[[24507,87958],[-46,122],[-204,72],[14,-166],[209,-170],[27,142]],[[36077,79561],[-162,155],[-77,218],[-247,266],[-169,42],[-220,-111],[-89,-114],[-123,86],[-88,385],[-143,-63],[-245,275],[-355,17],[-159,-40],[-15,172],[-235,-18],[-35,-122],[-168,152],[-128,-192],[-90,410],[-142,-20],[-116,552],[-221,29],[-73,68],[-172,-11],[-137,150],[-247,71],[-141,355],[11,415]],[[30140,68374],[105,214],[-4,258],[85,136],[608,264],[33,-112],[150,203],[662,513],[11,198],[-92,403],[295,290],[59,128],[33,339],[-13,769],[-32,764],[-95,318],[215,561],[313,56],[386,-90],[207,-115],[-3,163],[284,198],[408,116],[71,107],[319,186],[-12,146],[-185,411],[-221,1041],[-9,292],[548,83],[-199,226],[-161,330],[904,770],[398,324],[-112,200],[117,-34],[120,-302],[205,-125],[334,1412],[67,240],[138,306]],[[28903,79898],[75,-206],[60,67],[93,-391],[301,-54],[171,372],[319,-579],[198,-613],[237,-497],[-196,-205],[-53,27],[-122,-209],[-267,84],[-192,224],[-139,-546],[-173,-433],[-291,-393],[-131,-29],[-105,-297],[-184,-177],[-252,23],[-259,-381],[-180,-116],[-134,-259],[-88,-413],[-259,-480],[146,-447],[127,-186],[277,-587],[211,-221],[315,-38],[11,-82],[-178,-45],[-340,-2],[-122,62],[-389,-102],[-68,136],[-64,-95],[-91,64],[-38,-238],[-157,-366],[-127,-23],[-70,-578],[153,-1360]],[[32091,82688],[-239,-85],[-38,-119],[-244,-241],[-347,-85],[-59,-300],[-270,-120],[-332,-82],[-58,-218],[100,-354],[-64,-618],[-70,-296],[-144,-155],[-231,26],[-172,260],[-168,-337],[-167,245],[-396,21],[-289,-332]],[[44572,88459],[-214,4],[-366,-89],[-258,38],[-266,164],[-208,0],[-76,-495],[-5,-214],[-89,-499],[-192,-16],[-206,162],[-23,284],[-77,246],[-9,363],[-373,82],[24,-198],[-233,-52],[-296,-135],[-104,16],[-169,-125],[-168,40],[-12,-242],[96,-326],[33,-326],[-151,-76],[-34,159],[-284,125],[-171,218],[-119,-147],[-552,-306],[-247,-55],[4,-80],[-183,106],[-292,281],[-141,226],[-133,-282],[29,-559],[0,-559],[-85,2],[-321,206],[-365,22],[9,-154],[-136,12],[-67,242],[-219,-183],[-373,-207],[-96,174],[-110,59],[-298,-37],[-76,-541],[-212,-231],[-159,285],[-184,119],[10,173],[-108,67],[-129,-226],[-473,500],[-109,48],[-94,-183],[-159,-64],[-177,40],[-382,-21],[-176,-102],[-14,328]],[[43406,77708],[-154,204],[-25,273],[33,184],[-96,160],[64,407],[285,98],[141,211],[33,200],[277,439],[30,202],[154,169],[145,241],[79,327],[25,394],[231,108],[2,464],[287,186],[143,194],[58,278],[141,315],[27,274],[-79,352],[-176,347],[129,717],[-5,166],[74,94],[79,330],[-103,164],[-154,502],[56,184],[-18,517],[-116,-274],[-397,-177],[-21,51],[110,560],[158,487],[341,174],[96,293],[-28,207],[172,300],[-239,121],[-579,-214],[41,176],[-55,346]],[[43290,77585],[116,123]],[[38763,73868],[277,110],[201,24],[544,148],[178,87],[-147,330],[-96,26],[-42,369],[163,404],[-45,613],[756,-43],[123,202],[-24,173],[655,78],[310,79],[274,272],[53,269],[69,3],[70,194],[128,-96],[282,264],[31,-111],[233,118],[72,-87],[150,134],[191,-41],[121,198]],[[36077,79561],[117,-69],[-4,-147],[104,-32],[183,-265],[183,-174],[38,-276],[-45,-354],[74,-339],[120,-210],[32,-220],[-109,-275],[-181,-115],[-119,-174],[20,-264],[184,-170],[-38,-409],[64,-411],[128,-510],[-176,-209],[106,-570],[195,93],[-5,87],[441,180],[-81,-349],[314,99],[152,-19],[322,57],[62,-143],[629,7],[-62,-253],[38,-259]],[[34604,86520],[-299,-288],[-63,-172],[-174,-240],[-275,-631],[-93,294],[-203,-69],[126,-484],[-95,-315],[-83,-472],[-124,-173],[-105,-16],[-234,-172],[-240,-390],[-145,-146],[-219,-571],[-287,13]],[[28903,79898],[-404,-461]],[[19398,82157],[-74,-664],[-110,-288],[116,-163],[-109,-217],[-101,-36],[-186,-508],[-58,27],[-85,-344],[72,-27],[-64,-363],[-294,128],[-25,-469],[-221,140],[-43,-285],[-113,34],[-54,-237],[-113,75],[-17,-583],[70,5],[-21,-472],[-125,87],[-68,-557],[252,-85],[-98,-97],[4,-159],[165,40],[0,-184],[-175,-147],[17,-344],[-102,-30],[-70,-155],[162,-241],[-81,-184],[151,-146],[73,24],[-99,-219],[-224,-54],[-85,-380],[-237,-32],[-35,-337],[-199,41],[-208,-153],[-111,-667],[13,-693],[-98,-301],[88,-113]],[[21022,81364],[-1551,792],[-73,1]],[[34505,88214],[-195,-37],[-250,-526],[-163,-253],[-100,-37],[-464,81],[-135,-229],[-133,-103],[-281,100],[-226,-9],[-211,140],[-41,-185],[-217,-590],[-371,-477],[-241,-455],[-274,-258],[-312,174],[-193,195],[-4,214],[-133,-10],[-201,-268],[-128,66],[-121,-185],[-271,-183],[-91,-124],[-195,-469],[-226,-312],[-271,-121],[-488,41],[-363,-52],[-194,114],[-70,122]],[[34604,86520],[-7,260],[-256,526],[172,567],[-8,341]],[[38763,73868],[2,-341],[-49,-765],[88,-139],[-83,-64],[51,-382],[47,3],[78,-345],[-28,-247],[45,-311],[19,-622],[-35,-1045],[215,-1680],[-8,-103]],[[43303,65237],[99,501],[-59,47],[71,528],[76,194],[-354,351],[-179,348],[-76,63],[-327,41],[-149,-50],[-182,-151],[-206,-348],[-134,313],[-97,679],[206,797],[76,-4],[156,-324],[10,183],[361,688],[39,122],[128,760],[-545,291],[508,1050],[223,377],[301,388],[423,386],[376,283],[289,180],[35,487],[119,3],[-13,505],[-57,362],[-186,-91],[-36,55],[-91,594],[-546,-160],[10,409],[66,240],[216,83],[-34,555],[-407,-58],[-13,543],[365,60],[-47,628],[-36,166],[-276,-113],[-116,387]],[[49547,85544],[-80,89],[-54,296],[-178,227],[-106,-48],[-327,18],[-66,-231],[-142,49],[-273,-442],[-224,-469],[-77,227],[-231,12],[-52,342],[-248,-118],[-220,-283],[-102,-38],[-22,353],[82,173],[-7,399],[-38,358],[-199,718],[149,336],[-496,221],[-60,114],[-152,79],[-301,-106],[-212,-23],[-49,187],[-160,256],[21,241]],[[43406,77708],[340,69],[64,135],[174,118],[70,-61],[359,113],[420,261],[338,-36],[138,113],[123,-102],[160,97],[95,-48],[93,102],[143,14],[155,143],[172,-32],[32,75],[231,80],[15,72],[196,91],[249,-126],[306,246],[180,-247],[-22,-207]],[[44687,88839],[-45,-288],[-70,-92]],[[48703,94767],[-155,-115],[-493,-14],[-371,176],[-193,-164],[-207,-45],[-262,60],[10,96],[-174,60],[-272,-39],[-214,-406],[-108,-76],[-206,-14]],[[41175,93583],[-146,-67],[-277,81],[-348,-147],[-124,-163],[-593,-489],[-391,-222],[-323,323],[-336,-82],[-271,-394],[-104,-402],[27,-266],[-36,-195],[-228,-253],[-123,-4],[-295,126],[-190,-4],[-57,-293],[-172,-647],[89,-429],[-117,-345],[-126,-144],[-530,-462],[-357,-411],[-176,-34],[-368,391],[-76,15],[-195,-316],[-44,-261],[-272,-429],[-267,-153],[-244,307]],[[22578,86629],[-193,203],[-85,-287],[-384,384],[31,129],[-111,121],[250,253],[-111,244],[86,239],[141,-131],[109,304],[303,697],[72,265],[114,188],[105,381],[-217,248],[-328,187],[-194,221],[-175,125],[-576,263],[-183,200],[-143,524],[-64,726],[-96,379],[-349,616],[-374,419],[-300,371],[-192,100],[-228,7],[-141,83],[-366,328],[-380,273],[-379,205],[-141,21],[-209,-59],[-551,-298],[-147,26],[-287,316],[-174,109],[-248,-59],[-122,-137],[-309,-484]],[[16591,90876],[261,-164],[0,-166],[-131,-100],[-12,-473],[-70,-558],[186,-70],[12,-581],[-72,-1147],[112,-65],[-35,-789],[352,-131],[272,-41],[180,-151],[412,-478],[95,71],[40,-222],[111,150],[204,-158],[315,-24],[447,-336],[73,-174],[129,-95],[20,-266],[-50,-574],[136,-285],[-11,-299],[115,-454],[-36,-611],[-81,-374],[-167,-154]],[[47124,63217],[-1198,97],[-289,140],[-1590,1221],[-744,562]],[[50392,62602],[-42,-25],[-213,224],[-55,164],[-120,-122],[-250,185],[172,457],[-395,257],[-106,-240],[-168,429],[-216,-91],[-87,154],[-94,-365],[-586,309],[-140,-990],[-420,222],[-548,47]],[[49639,60899],[694,1374],[-37,49],[96,280]],[[46529,55166],[286,71],[278,-203],[352,209],[183,9],[145,108],[115,300],[136,79],[22,158],[-148,35],[-109,172],[87,317],[130,78],[184,-16],[-1,390],[344,-57],[47,152],[141,21],[41,345],[189,3],[202,338],[6,131],[260,323],[166,575],[-51,43],[126,571],[-444,227],[95,348],[73,498],[255,508]],[[58526,59319],[1311,145],[623,-268],[856,-554],[-22,565],[156,-14],[-26,554],[284,117],[533,-65],[76,25],[-148,887],[-137,913],[519,230],[17,254],[289,19],[179,67],[-2,-667],[-68,-11],[157,-489],[420,-508],[123,274],[212,35],[281,328],[70,251],[42,-46],[155,199],[291,140],[186,169],[128,202],[71,329],[-100,580],[4,274],[113,249]],[[58703,67444],[145,-266],[-110,-353],[13,-245],[81,-129],[-77,-157],[79,-79],[-110,-98],[119,-418],[-97,-145],[-84,-409],[16,-181],[-102,-40],[71,-409],[225,-695],[19,-626],[62,-203],[-149,-129],[-121,108],[-20,139],[-352,-133],[-77,222],[74,-737],[-183,-452],[-99,-123],[-37,-586],[39,-177],[-72,-679],[49,-39],[347,54],[207,-13],[-33,-1127]],[[65119,63503],[-111,440],[-164,208],[-276,-90],[0,406],[-50,354],[-101,167],[-63,-106],[-157,251],[17,61],[-140,402],[-24,393],[159,445],[-96,395],[-86,11],[-87,462],[90,73],[12,377],[-76,608],[-26,459],[248,241],[124,483],[29,-80],[178,240],[159,39],[107,181],[-51,73],[135,291],[313,-45],[151,-220],[178,489],[64,-235],[140,88],[39,118],[145,-79]],[[65119,63503],[251,318],[134,-599],[162,-36],[85,-1044],[-151,-53],[-79,-267],[57,-648],[-144,-81],[20,-304],[-57,-136],[2,-236],[124,-309],[-12,-205]],[[56951,55395],[-109,-446],[648,-305],[131,-167],[15,-355],[-476,-105],[-23,-1101],[215,-56],[677,-336],[-14,-188],[114,-201],[8,-335],[146,-196],[-44,-267],[262,-227],[-34,-269],[148,-165]],[[58526,59319],[-676,-91],[-260,92],[-37,-153],[-178,-1135],[-55,-223],[-106,-850],[-75,-254],[-35,-399],[-153,-911]],[[56951,55395],[-552,68],[-325,103],[-176,124],[-1391,1099],[-163,147],[-362,455],[-326,284],[-178,94],[-1280,518],[-420,243],[-301,271],[-1441,1542],[-397,556]],[[50392,62602],[329,197],[-68,367],[-3,230],[128,-104],[192,373],[191,534],[398,964],[201,409],[-67,107],[279,324],[109,341],[393,428],[189,81],[129,208],[220,-56],[108,-88],[420,-136],[-63,-112],[394,-169],[360,16],[146,196],[112,40],[68,270]],[[53228,72957],[-137,-108],[0,-209],[-329,129],[-183,-118],[-346,-108],[-84,96],[-115,-137],[-170,-14],[-49,-135],[-208,-25],[-74,-198],[-82,-18],[-159,-247],[-273,-104],[-302,-35],[-245,23],[-180,-216],[-185,-57],[-125,-128],[-174,175],[-312,-73],[-141,68],[-135,-156],[-226,-510],[-207,3],[-125,-293],[-239,121],[-212,209],[-102,33],[-226,-185],[-108,-210],[21,-599],[-115,-924],[-45,-145],[-261,-424],[169,-201],[-82,-459],[107,-110],[-55,-502],[-32,-707],[-223,43],[-182,-58],[1,-577],[-91,-20],[-39,-266],[224,-1198],[36,-387],[-84,-779]]],"transform":{"scale":[0.008364317083074108,-0.004800048000480004],"translate":[61.7883280048361,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/ti.json b/src/onegov/election_day/static/mapdata/2025/ti.json new file mode 100644 index 0000000000..ea95a75f42 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/ti.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":5001,"properties":{"id":5001,"name":"Arbedo-Castione"},"arcs":[[-1,-2,-3]]},{"type":"Polygon","id":5002,"properties":{"id":5002,"name":"Bellinzona"},"arcs":[[-4,-5,-6,-7,-8,-9,-10,0,-11,-12,-13,-14]]},{"type":"Polygon","id":5003,"properties":{"id":5003,"name":"Cadenazzo"},"arcs":[[-15,-16,-17,-18,4,-19,-20]]},{"type":"Polygon","id":5009,"properties":{"id":5009,"name":"Isone"},"arcs":[[19,-21,13,-22,-23,-24,-25]]},{"type":"Polygon","id":5010,"properties":{"id":5010,"name":"Lumino"},"arcs":[[-26,1,9]]},{"type":"Polygon","id":5017,"properties":{"id":5017,"name":"Sant'Antonino"},"arcs":[[20,18,3]]},{"type":"Polygon","id":5048,"properties":{"id":5048,"name":"Acquarossa"},"arcs":[[-27,-28,-29]]},{"type":"Polygon","id":5049,"properties":{"id":5049,"name":"Blenio"},"arcs":[[-30,26,-31,-32,-33]]},{"type":"Polygon","id":5050,"properties":{"id":5050,"name":"Serravalle"},"arcs":[[-34,27,29,-35,-36,-37,-38]]},{"type":"Polygon","id":5061,"properties":{"id":5061,"name":"Airolo"},"arcs":[[-39,-40,-41,-42]]},{"type":"Polygon","id":5063,"properties":{"id":5063,"name":"Bedretto"},"arcs":[[40,-43,-44,-45]]},{"type":"Polygon","id":5064,"properties":{"id":5064,"name":"Bodio"},"arcs":[[37,-46,-47,-48,-49]]},{"type":"Polygon","id":5071,"properties":{"id":5071,"name":"Dalpe"},"arcs":[[-50,-51,-52]]},{"type":"Polygon","id":5072,"properties":{"id":5072,"name":"Faido"},"arcs":[[-53,-54,30,28,33,48,-55,-56,-57,49]]},{"type":"Polygon","id":5073,"properties":{"id":5073,"name":"Giornico"},"arcs":[[-58,54,47,-59]]},{"type":"Polygon","id":5076,"properties":{"id":5076,"name":"Personico"},"arcs":[[58,46,-60,-61,-62]]},{"type":"Polygon","id":5077,"properties":{"id":5077,"name":"Pollegio"},"arcs":[[59,45,36,-63,-64]]},{"type":"Polygon","id":5078,"properties":{"id":5078,"name":"Prato (Leventina)"},"arcs":[[51,-65,-66,52]]},{"type":"Polygon","id":5079,"properties":{"id":5079,"name":"Quinto"},"arcs":[[-67,31,53,65,-68,38]]},{"type":"Polygon","id":5091,"properties":{"id":5091,"name":"Ascona"},"arcs":[[-69,-70,-71,-72,-73]]},{"type":"Polygon","id":5096,"properties":{"id":5096,"name":"Brione sopra Minusio"},"arcs":[[-74,-75,-76,-77],[77]]},{"type":"MultiPolygon","id":5097,"properties":{"id":5097,"name":"Brissago"},"arcs":[[[-79,-80,-81]],[[-82]]]},{"type":"Polygon","id":5108,"properties":{"id":5108,"name":"Gordola"},"arcs":[[-83,-84,-85,-86,-87,-88]]},{"type":"Polygon","id":5112,"properties":{"id":5112,"name":"Lavertezzo"},"arcs":[[87,-89,-90]]},{"type":"MultiPolygon","id":5113,"properties":{"id":5113,"name":"Locarno"},"arcs":[[[-91,-92,-93,-94,-95,-96,-97,68]],[[-98,-99,82,89,-100,16]]]},{"type":"Polygon","id":5115,"properties":{"id":5115,"name":"Losone"},"arcs":[[72,-101,-102,90]]},{"type":"Polygon","id":5117,"properties":{"id":5117,"name":"Mergoscia"},"arcs":[[84,-103,73,-104,-105]]},{"type":"Polygon","id":5118,"properties":{"id":5118,"name":"Minusio"},"arcs":[[-106,75,-107,-108,95,-109,-110]]},{"type":"Polygon","id":5120,"properties":{"id":5120,"name":"Muralto"},"arcs":[[94,-111,108]]},{"type":"Polygon","id":5121,"properties":{"id":5121,"name":"Orselina"},"arcs":[[109,110,93]]},{"type":"Polygon","id":5125,"properties":{"id":5125,"name":"Ronco sopra Ascona"},"arcs":[[80,70,-112],[81]]},{"type":"MultiPolygon","id":5131,"properties":{"id":5131,"name":"Tenero-Contra"},"arcs":[[[106,74,102,83,98,-113]],[[-78]]]},{"type":"Polygon","id":5136,"properties":{"id":5136,"name":"Onsernone"},"arcs":[[-114,-115,-116,-117,-118]]},{"type":"Polygon","id":5138,"properties":{"id":5138,"name":"Cugnasco-Gerra"},"arcs":[[88,86,-119,5,17,99]]},{"type":"Polygon","id":5141,"properties":{"id":5141,"name":"Agno"},"arcs":[[-120,-121,-122,-123,-124,-125]]},{"type":"Polygon","id":5143,"properties":{"id":5143,"name":"Aranno"},"arcs":[[-126,-127,-128,-129,-130,-131]]},{"type":"Polygon","id":5144,"properties":{"id":5144,"name":"Arogno"},"arcs":[[-132,-133,-134,-135,-136]]},{"type":"Polygon","id":5146,"properties":{"id":5146,"name":"Astano"},"arcs":[[-137,-138,-139,-140,-141]]},{"type":"Polygon","id":5148,"properties":{"id":5148,"name":"Bedano"},"arcs":[[-142,-143,-144,-145]]},{"type":"MultiPolygon","id":5149,"properties":{"id":5149,"name":"Bedigliora"},"arcs":[[[-146,-147,-148,-149]],[[139,-150,-151]]]},{"type":"Polygon","id":5151,"properties":{"id":5151,"name":"Bioggio"},"arcs":[[-152,-153,-154,-155,-156,-157,122,-158,-159,129]]},{"type":"Polygon","id":5154,"properties":{"id":5154,"name":"Bissone"},"arcs":[[-160,-161,-162,132,-163,-164]]},{"type":"Polygon","id":5160,"properties":{"id":5160,"name":"Brusino Arsizio"},"arcs":[[-165,-166,159,-167,-168,-169,-170]]},{"type":"Polygon","id":5161,"properties":{"id":5161,"name":"Cademario"},"arcs":[[128,-171,151]]},{"type":"Polygon","id":5162,"properties":{"id":5162,"name":"Cadempino"},"arcs":[[-172,-173,-174,-175]]},{"type":"Polygon","id":5167,"properties":{"id":5167,"name":"Canobbio"},"arcs":[[-176,-177,-178,-179]]},{"type":"Polygon","id":5171,"properties":{"id":5171,"name":"Caslano"},"arcs":[[-180,-181,-182,-183,-184,-185]]},{"type":"Polygon","id":5176,"properties":{"id":5176,"name":"Comano"},"arcs":[[178,-186,-187,-188,-189]]},{"type":"Polygon","id":5180,"properties":{"id":5180,"name":"Cureglia"},"arcs":[[174,-190,-191,186,-192,-193]]},{"type":"MultiPolygon","id":5181,"properties":{"id":5181,"name":"Curio"},"arcs":[[[-194,147,-195,130,158,-196,-197,-198]],[[-199,140,150,-200,145]]]},{"type":"Polygon","id":5186,"properties":{"id":5186,"name":"Grancia"},"arcs":[[-201,-202]]},{"type":"Polygon","id":5187,"properties":{"id":5187,"name":"Gravesano"},"arcs":[[-203,-204,-205,141]]},{"type":"Polygon","id":5189,"properties":{"id":5189,"name":"Lamone"},"arcs":[[144,-206,-207,189,173,-208,202]]},{"type":"Polygon","id":5192,"properties":{"id":5192,"name":"Lugano"},"arcs":[[-209,-210,-211,-212,176,-213,-214,-215,-216,-217,134,-218,-219,-220,-221,-222,182,-223,200,-224,-225,-226,155,-227],[-228]]},{"type":"Polygon","id":5193,"properties":{"id":5193,"name":"Magliaso"},"arcs":[[180,-229,-230,119,-231]]},{"type":"Polygon","id":5194,"properties":{"id":5194,"name":"Manno"},"arcs":[[-232,153,-233,203,207,172]]},{"type":"Polygon","id":5196,"properties":{"id":5196,"name":"Massagno"},"arcs":[[-234,209]]},{"type":"Polygon","id":5198,"properties":{"id":5198,"name":"Melide"},"arcs":[[218,-235,160,165,-236]]},{"type":"MultiPolygon","id":5199,"properties":{"id":5199,"name":"Mezzovico-Vira"},"arcs":[[[-237,-238]],[[-239,-240,-241,-242]]]},{"type":"Polygon","id":5200,"properties":{"id":5200,"name":"Miglieglia"},"arcs":[[-243,-244,-245,126]]},{"type":"Polygon","id":5203,"properties":{"id":5203,"name":"Morcote"},"arcs":[[169,-246,220,-247]]},{"type":"Polygon","id":5205,"properties":{"id":5205,"name":"Muzzano"},"arcs":[[123,156,225,-248,-249]]},{"type":"Polygon","id":5206,"properties":{"id":5206,"name":"Neggio"},"arcs":[[196,-250,120,229,-251]]},{"type":"Polygon","id":5207,"properties":{"id":5207,"name":"Novaggio"},"arcs":[[194,146,199,149,138,-252,242,125]]},{"type":"Polygon","id":5208,"properties":{"id":5208,"name":"Origlio"},"arcs":[[-253,187,190,206,-254,-255]]},{"type":"Polygon","id":5210,"properties":{"id":5210,"name":"Paradiso"},"arcs":[[227]]},{"type":"MultiPolygon","id":5212,"properties":{"id":5212,"name":"Ponte Capriasca"},"arcs":[[[-256,215,-257,22,-258,11]],[[254,-259,-260,-261,-262,-263]]]},{"type":"Polygon","id":5214,"properties":{"id":5214,"name":"Porza"},"arcs":[[191,185,177,211,-264,-265]]},{"type":"Polygon","id":5216,"properties":{"id":5216,"name":"Pura"},"arcs":[[-266,197,250,228,179]]},{"type":"Polygon","id":5221,"properties":{"id":5221,"name":"Savosa"},"arcs":[[-267,263,210,233,208]]},{"type":"Polygon","id":5225,"properties":{"id":5225,"name":"Sorengo"},"arcs":[[-268,247,224]]},{"type":"MultiPolygon","id":5226,"properties":{"id":5226,"name":"Capriasca"},"arcs":[[[-269,23,256,214,-270,212,175,188,252,262,-271,237]],[[260,-272]]]},{"type":"Polygon","id":5227,"properties":{"id":5227,"name":"Torricella-Taverne"},"arcs":[[-273,258,253,205,143,-274,239]]},{"type":"Polygon","id":5230,"properties":{"id":5230,"name":"Vernate"},"arcs":[[157,121,249,195]]},{"type":"Polygon","id":5231,"properties":{"id":5231,"name":"Vezia"},"arcs":[[192,264,266,226,154,231,171]]},{"type":"Polygon","id":5233,"properties":{"id":5233,"name":"Vico Morcote"},"arcs":[[246,219,235,164]]},{"type":"Polygon","id":5236,"properties":{"id":5236,"name":"Collina d'Oro"},"arcs":[[230,124,248,267,223,201,222,181]]},{"type":"Polygon","id":5237,"properties":{"id":5237,"name":"Alto Malcantone"},"arcs":[[232,152,170,127,244,-275,-276,240,273,142,204]]},{"type":"Polygon","id":5238,"properties":{"id":5238,"name":"Monteceneri"},"arcs":[[14,24,268,236,270,261,271,259,272,238,-277]]},{"type":"Polygon","id":5239,"properties":{"id":5239,"name":"Tresa"},"arcs":[[265,184,-278,136,198,148,193]]},{"type":"Polygon","id":5240,"properties":{"id":5240,"name":"Val Mara"},"arcs":[[-279,-280,-281,-282,162,131]]},{"type":"Polygon","id":5242,"properties":{"id":5242,"name":"Balerna"},"arcs":[[-283,-284,-285,-286,-287]]},{"type":"Polygon","id":5249,"properties":{"id":5249,"name":"Castel San Pietro"},"arcs":[[-288,286,-289,-290,279,-291,-292]]},{"type":"Polygon","id":5250,"properties":{"id":5250,"name":"Chiasso"},"arcs":[[-293,-294,-295,283,-296]]},{"type":"Polygon","id":5251,"properties":{"id":5251,"name":"Coldrerio"},"arcs":[[288,285,-297,-298]]},{"type":"Polygon","id":5254,"properties":{"id":5254,"name":"Mendrisio"},"arcs":[[-299,-300,167,-301,280,289,297,-302,-303]]},{"type":"Polygon","id":5257,"properties":{"id":5257,"name":"Morbio Inferiore"},"arcs":[[287,-304,-305,295,282]]},{"type":"Polygon","id":5260,"properties":{"id":5260,"name":"Novazzano"},"arcs":[[-306,301,296,284,294]]},{"type":"Polygon","id":5263,"properties":{"id":5263,"name":"Riva San Vitale"},"arcs":[[166,163,281,300]]},{"type":"Polygon","id":5266,"properties":{"id":5266,"name":"Stabio"},"arcs":[[-307,298]]},{"type":"Polygon","id":5268,"properties":{"id":5268,"name":"Vacallo"},"arcs":[[-308,292,304,-309]]},{"type":"Polygon","id":5269,"properties":{"id":5269,"name":"Breggia"},"arcs":[[291,-310,308,303]]},{"type":"Polygon","id":5281,"properties":{"id":5281,"name":"Biasca"},"arcs":[[-311,62,35,-312]]},{"type":"Polygon","id":5287,"properties":{"id":5287,"name":"Riviera"},"arcs":[[63,310,-313,7,-314,60]]},{"type":"Polygon","id":5304,"properties":{"id":5304,"name":"Bosco/Gurin"},"arcs":[[-315,-316,-317,-318]]},{"type":"Polygon","id":5307,"properties":{"id":5307,"name":"Campo (Vallemaggia)"},"arcs":[[317,-319,-320,-321,116,-322]]},{"type":"Polygon","id":5309,"properties":{"id":5309,"name":"Cerentino"},"arcs":[[-323,318,316,-324,-325]]},{"type":"Polygon","id":5310,"properties":{"id":5310,"name":"Cevio"},"arcs":[[-326,323,315,-327,43,-328,-329,319,322]]},{"type":"Polygon","id":5315,"properties":{"id":5315,"name":"Linescio"},"arcs":[[324,325]]},{"type":"Polygon","id":5317,"properties":{"id":5317,"name":"Maggia"},"arcs":[[117,320,328,-330,-331,-332]]},{"type":"Polygon","id":5323,"properties":{"id":5323,"name":"Lavizzara"},"arcs":[[50,56,-333,327,42,39,67,64]]},{"type":"Polygon","id":5324,"properties":{"id":5324,"name":"Avegno Gordevio"},"arcs":[[76,105,92,-334,330,-335,103]]},{"type":"Polygon","id":5391,"properties":{"id":5391,"name":"Comunanza Cadenazzo/Monteceneri"},"arcs":[[257,21,12]]},{"type":"Polygon","id":5394,"properties":{"id":5394,"name":"Comunanza Capriasca/Lugano"},"arcs":[[269,213]]},{"type":"Polygon","id":5396,"properties":{"id":5396,"name":"Terre di Pedemonte"},"arcs":[[331,333,91,101,-336,113]]},{"type":"Polygon","id":5397,"properties":{"id":5397,"name":"Centovalli"},"arcs":[[79,-337,114,335,100,71]]},{"type":"Polygon","id":5398,"properties":{"id":5398,"name":"Gambarogno"},"arcs":[[69,96,107,112,97,15,276,241,275,-338,111]]},{"type":"Polygon","id":5399,"properties":{"id":5399,"name":"Verzasca"},"arcs":[[61,313,6,118,85,104,334,329,332,55,57]]}]}},"arcs":[[[86299,52133],[-81,-8],[-2048,-669],[-130,-71],[-579,443],[-359,-259],[475,-293],[464,-1214],[93,-515],[279,-308],[-24,-283],[258,-80],[-192,-524],[49,-308],[-125,-418],[302,-110],[738,13],[814,149],[329,-93],[363,-402],[-26,-194],[146,-299],[-12,-389],[187,-291],[237,-111],[383,-342],[1249,-93],[560,-304],[513,-137],[706,65],[1248,-129],[393,-109],[260,26],[449,-125],[334,-200],[464,-98],[601,89],[1003,-118],[266,15],[834,-110],[643,219]],[[90807,48601],[-366,-284],[-495,142],[-249,-100],[-883,473],[69,94],[-2329,911],[-360,91],[-312,261],[-198,967],[258,239],[357,738]],[[97363,44548],[-493,204],[-559,537],[-42,441],[-177,114],[-621,691],[-282,64],[-403,501],[-469,294],[-398,156],[-251,182],[-373,77],[-2488,792]],[[70862,42423],[2069,217],[78,-211],[526,79],[25,-60],[526,143],[111,-200],[510,143],[236,-384],[848,289],[297,-338],[432,137],[74,-97],[459,157],[681,-844],[470,226],[659,-140],[488,-574],[181,-348],[-11,-469]],[[69893,42321],[969,102]],[[70600,50916],[822,-34],[191,-83],[215,-478],[249,-305],[-141,-330],[-299,-371],[52,-450],[-236,-506],[58,-236],[-238,-697],[-341,-432],[-44,-338],[-153,-138],[239,-350],[-99,-832],[-62,-171],[-86,-887],[-193,-704],[-203,17],[52,-418],[349,62],[-70,-358],[-929,-168],[160,-388]],[[69629,53411],[197,-320],[-157,-477],[-914,-993],[52,-121],[574,-249],[368,-103],[512,-5],[339,-227]],[[86222,58823],[-1299,152],[-369,-54],[-526,-447],[-513,-130],[-483,-224],[-64,-124],[-707,-263],[-350,-22],[-141,-114],[-373,-71],[14,-145],[-513,-310],[215,-973],[-484,-154],[-123,103],[-443,-207],[-712,102],[-270,175],[-242,565],[-31,1022],[-87,441],[-679,-341],[113,-273],[-211,-190],[112,-126],[-106,-372],[164,-538],[-343,-138],[-1710,35],[-122,-159],[-210,7],[-316,-314],[-603,102],[-161,-324],[-647,-413],[-540,-13],[-334,-141],[-159,553],[-70,-232],[-280,-248],[-332,-120],[-306,-213],[-1375,-488],[29,-288],[-98,-481],[-226,88],[-682,-107]],[[87182,56447],[-49,136],[-426,314],[-610,1231],[-108,324],[33,217],[200,154]],[[86299,52133],[77,206],[-47,452],[354,260],[190,248],[60,544],[194,417],[-267,373],[408,133],[-123,448],[76,657],[-163,477],[124,99]],[[89834,37382],[849,217],[52,108],[459,207],[782,111],[228,118],[306,-51],[92,252],[534,413],[708,168],[224,172],[618,95],[503,-100],[236,359],[-20,162],[526,568],[-26,187],[263,320],[423,257],[251,480],[798,213],[464,431],[633,269],[741,131],[211,134],[193,294],[117,532],[-60,54],[-747,50],[-461,227],[-1044,704],[-324,84]],[[88373,39020],[192,-321],[323,-159],[119,-390],[772,-511],[55,-257]],[[83834,40457],[833,365],[858,-65],[783,76],[187,-97],[267,79],[388,-382],[311,176],[57,-229],[182,-117],[678,-725],[92,-357],[-97,-161]],[[79521,40149],[1230,371],[397,30],[157,-204],[587,-55],[134,-105],[779,-166],[128,213],[324,32],[577,192]],[[71508,39949],[-1048,-147],[30,-214],[230,-341],[394,-39],[99,-117],[454,-67],[148,-128],[1394,-127],[319,-443],[405,186],[723,190],[516,34],[834,-82],[473,95]],[[69455,41687],[1043,-180],[658,-70],[51,-389],[406,-39],[101,-554],[98,-7],[246,-438],[-550,-61]],[[69330,42128],[125,-441]],[[69893,42321],[-611,-96],[48,-97]],[[77215,39212],[-457,388],[-527,366],[-1343,1029],[-126,-5],[-216,454],[-509,-173],[-280,690],[-585,-91],[-235,234],[-1208,-217],[-179,270],[-563,-16],[-125,282]],[[76479,38749],[-201,90],[223,194],[714,179]],[[79521,40149],[-443,-195],[-1188,-603],[-675,-139]],[[87440,38717],[-524,-43],[-151,150],[-357,80],[-247,160],[54,593],[-167,110],[-801,309],[-537,29],[-201,-250],[-305,-91],[-221,163],[-149,530]],[[82932,37791],[686,-30],[287,-225],[404,99],[177,-40],[411,170],[178,-164],[338,111],[643,-258],[255,6],[372,179],[757,1078]],[[77972,36479],[157,-30],[197,228],[35,370],[192,174],[-216,61],[372,393],[622,284],[370,265],[687,233],[792,-268],[604,-121],[60,-138],[906,-37],[182,-102]],[[76479,38749],[-247,-241],[20,-274],[-182,-663],[197,-148],[774,-354],[31,100],[336,-125],[328,-530],[236,-35]],[[90807,48601],[-284,231],[-396,679],[-162,668],[-444,974],[-384,-42],[-254,-158],[-419,528],[582,230],[72,2557],[64,202],[-659,736],[-77,165],[-545,346],[-570,296],[-149,434]],[[77482,80246],[-313,69],[-462,-55],[-270,69],[-439,-130],[-295,-164],[-1073,104],[-2878,670],[-812,40],[-458,-48],[115,272],[250,131],[-7,309],[503,268],[-163,373],[271,239],[-9,309],[217,144],[10,318],[-274,317],[-228,52],[-760,-91],[-161,137],[-316,-315],[-119,-335],[-140,17],[-387,-198],[-323,65],[-114,-463],[-417,27],[-768,-97],[-805,99],[-965,300],[-795,496],[92,138],[-86,1010],[-1098,-125],[-328,68],[-1051,-288],[-181,65],[-409,-252],[-1100,201]],[[68188,73352],[887,578],[1018,206],[199,98],[-576,138],[1495,803],[354,-108],[734,-326],[222,-25],[674,595],[524,-165],[814,-402],[489,31],[495,-165],[-58,-201],[175,-217],[293,335],[1034,76],[-42,144],[158,247],[-14,716],[202,428],[892,267],[361,295],[203,329],[-94,375],[-302,324],[103,284],[-102,356],[-403,535],[129,404],[30,346],[-276,214],[-324,379]],[[60936,83992],[-122,-178],[463,-296],[87,-232],[-245,-410],[186,-678],[-370,-296],[-35,-285],[157,-121],[504,-136],[146,-290],[279,-225],[-760,-732],[218,-352],[161,-471],[441,-219],[26,-183],[358,-606],[83,-236],[382,-313],[215,-276],[342,-197],[219,-222],[571,-383],[189,-32],[524,-533],[576,-437],[-80,-299],[477,-395],[295,-8],[199,-355],[265,-231],[670,-321],[237,-427],[304,-196],[290,-69]],[[77482,80246],[141,264],[457,563],[375,114],[223,173],[783,206],[326,167],[658,142],[303,252],[281,546],[139,-59],[1198,343],[581,4],[137,-180],[280,44]],[[48830,86508],[411,-232],[238,-328],[526,-206],[390,-218],[577,8],[28,134],[344,281],[234,-24],[450,206],[1009,92],[310,-52],[322,-178],[378,-321],[248,-21],[163,159],[786,-20],[329,-163],[536,-143],[251,5],[461,-176],[319,-16],[443,-243],[662,-248],[483,-69],[366,-188],[402,-306],[542,111],[898,-360]],[[50891,91774],[-588,-270],[565,-576],[-929,-2006],[-294,-267],[281,-340],[-368,-197],[-163,-272],[-359,-249],[322,-451],[-212,-490],[-316,-148]],[[83364,82825],[142,295],[-165,99],[-233,424],[-322,308],[-387,211],[-347,76],[-92,176],[-537,394],[-292,618],[75,270],[-77,335],[125,149],[-334,542],[20,435],[-130,186],[-351,50],[-81,368],[619,234],[161,495],[-226,211],[29,189],[-114,422],[-184,390],[425,551],[220,385],[-189,335],[424,464],[-14,512],[210,213],[177,451],[710,572],[-57,164],[248,591],[338,149],[489,28],[-218,241],[186,235],[-351,353],[-731,212],[-159,224],[-31,764],[-873,-86],[-254,250],[-296,39],[-275,171],[-579,-12],[-590,575],[-963,402],[-1125,34],[-1460,-378],[-1328,-774],[-818,120],[-562,-140],[-348,986],[393,920],[-697,1434],[-323,210],[-298,74],[-263,-290],[91,-215],[-131,-518],[-415,-210],[-212,-201],[-484,-276],[-338,54],[-725,232],[-929,71],[-159,189],[-477,-156],[-270,-265],[-875,-136],[-130,-254],[-359,-93],[-283,-498],[72,-320],[201,-425],[309,-347],[407,-327],[285,-113],[258,-342],[-214,-98],[120,-365],[-619,-516],[-944,-579],[-1227,-278],[-579,-352],[-1245,-204],[-306,-367],[-1208,-199],[-563,-21],[-157,-238],[-526,-154],[-229,35],[-604,-312],[-178,-146],[-774,-407],[-604,-31],[-855,84],[-128,98],[-144,366],[-16,447],[-3644,-1037],[-1982,517]],[[68188,73352],[12,-139],[386,-371],[526,-197],[114,-169],[512,-396]],[[89896,70284],[156,166],[95,312],[246,395],[560,364],[40,136],[-304,271],[-264,83],[-251,282],[100,214],[1295,432],[253,179],[-30,232],[-270,486],[-327,269],[-391,654],[-615,700],[-237,152],[53,589],[-352,825],[578,632],[26,554],[235,483],[121,398],[-204,308],[-489,510],[-621,462],[30,547],[-368,197],[-651,148],[-508,233],[-1051,-257],[-587,-253],[-798,46],[-423,307],[-345,59],[-385,182],[313,286],[-374,549],[-617,164],[-171,245]],[[72926,68741],[-122,87],[-242,608],[17,181],[1298,686],[1851,-209],[-35,-924],[1753,-577],[1007,-144],[145,258],[191,90],[-601,407],[130,353],[-300,57],[-569,396],[-386,-1],[-40,105],[336,227],[78,502],[800,-122],[548,-154],[1060,692],[705,333],[851,-49],[504,-111],[414,157],[642,-74],[731,-229],[329,-4],[251,-136],[354,-55],[678,41],[1226,-201],[448,-268],[519,-219],[492,-125],[679,19],[488,-86],[154,-119],[586,151]],[[71199,70018],[896,-35],[23,-503],[98,-533],[284,-281],[426,75]],[[69738,72080],[154,-424],[33,-559],[484,-351],[266,-309],[524,-419]],[[31853,82168],[347,306],[357,536],[31,182],[897,560],[728,298],[-153,297],[-640,160],[-277,215],[486,240],[94,140],[545,-147],[177,574],[431,30],[426,491],[140,-22],[255,457],[-29,294],[201,669],[93,144],[-200,220],[394,338],[420,198],[255,503],[6,320],[183,76],[406,437],[378,210],[299,466],[297,200],[160,313],[298,179],[102,256],[226,96],[-147,466],[44,156],[716,146],[594,69],[340,173]],[[22382,82157],[410,-100],[1345,245],[320,-37],[489,167],[-45,222],[309,411],[463,95],[229,-56],[817,109],[366,-19],[412,79],[1025,-354],[617,-75],[839,-170],[848,-382],[1027,-124]],[[17250,87892],[447,-105],[1107,1],[476,-146],[543,-606],[669,-533],[130,-390],[-434,-151],[-311,12],[489,-447],[481,-372],[-141,-146],[435,-541],[222,64],[116,-127],[270,-647],[34,-757],[145,-349],[454,-495]],[[40733,92414],[-77,409],[-235,195],[-472,82],[-113,197],[-220,-1],[-514,-177],[-256,87],[-626,0],[-284,-73],[-199,-186],[-387,94],[-197,-71],[-577,-22],[-199,-127],[-527,-116],[-502,-343],[-366,-26],[-244,-483],[-835,-385],[-1330,-328],[-774,23],[-98,118],[-385,52],[-264,609],[73,364],[-315,119],[-72,201],[-786,204],[-335,-71],[-355,72],[-30,-140],[-525,-269],[-1357,-181],[-242,68],[-931,-93],[-774,428],[-396,9],[-382,442],[-611,367],[-159,2],[-912,-304],[-827,22],[-508,-121],[-475,2],[-554,212],[-203,190],[-778,288],[-307,-189],[-646,-47],[-633,-380],[-178,-285],[21,-171],[-485,-76],[99,-327],[-241,-239],[139,-318],[7,-386],[-360,-185],[-619,-911],[59,-177],[300,-263],[-172,-363],[168,-358],[303,-228],[-43,-189],[353,-328],[-145,-165],[32,-276]],[[19772,79079],[362,96],[263,257],[691,195],[467,337],[174,348],[469,231],[-166,320],[200,69],[-129,186],[83,147],[-81,338],[277,554]],[[10167,76972],[740,625],[713,62],[408,92],[832,351],[113,107],[33,361],[649,114],[991,331],[213,-216],[286,101],[981,80],[486,330],[555,205],[79,159],[498,234],[294,66],[232,-328],[573,-161],[308,4],[621,-410]],[[17250,87892],[-430,-13],[-1029,-325],[-315,-138],[-519,-12],[-191,-114],[-604,37],[-467,-190],[-1105,-90],[-234,-382],[-388,-211],[116,-248],[-277,-175],[-441,-120],[-282,-315],[72,-56],[-625,-333],[16,-92],[-445,-307],[-282,-380],[-603,-387],[-495,-51],[-850,-1271],[-217,-264],[-694,93],[-403,104],[-356,-14],[-521,-252],[-404,-58],[-587,-239],[-673,255],[-420,-243],[-1226,-52],[-379,219],[-468,-53],[-307,95],[-86,-368],[307,-395],[98,-420],[-52,-160],[-356,-139],[-185,-297],[-363,-284],[-133,-275],[461,-375],[58,-352],[296,-14],[26,-200],[-502,-91],[-384,-211],[118,-321],[-73,-140],[-444,-318],[279,-801],[371,-99],[257,110],[477,-143],[374,370],[454,76],[320,-40],[317,298],[484,192],[673,76],[169,-85],[390,54],[341,224],[828,108],[535,227],[879,111],[105,-206],[810,143],[550,-225],[408,-449],[-38,-347],[354,-241],[827,-331]],[[69712,67570],[364,334],[-503,224],[514,278],[-158,269],[-229,-17],[622,344],[249,69],[214,255],[610,549],[-196,143]],[[65331,68796],[948,-334],[12,413],[283,21],[345,-103],[664,-344],[565,-393],[667,-5],[364,-69],[533,-412]],[[66220,69861],[-608,-242],[205,-193],[-329,-284],[43,-271],[-200,-75]],[[69738,72080],[-642,-245],[-484,-434],[-174,-440],[-406,-421],[-121,-278],[-126,-11],[-572,-348],[-993,-42]],[[41335,77620],[1535,-270],[937,-84],[656,-111],[369,-10],[801,-143],[116,-323],[415,-93],[301,43],[385,-81],[617,83],[178,-177],[902,-268],[-65,-89],[219,-331],[321,-335],[294,-449],[955,235],[906,589],[368,385],[240,373],[-572,205],[-922,415],[-232,229],[21,127],[-207,490],[475,284],[-14,243],[235,235],[866,82],[1082,160],[203,668],[-254,136],[-132,-93],[-546,47],[130,378],[-160,160],[-313,-17],[74,182],[-156,235],[-421,154],[-557,19],[-160,220],[-667,553],[-252,66]],[[42023,78355],[-467,-565],[-221,-170]],[[49306,81742],[-237,-322],[-591,-461],[-121,-564],[59,-175],[-344,-500],[186,-173],[26,-252],[-126,-250],[284,-381],[-636,186],[-366,0],[-76,-160],[-394,-173],[-611,3],[-325,-136],[-415,-72],[-749,161],[-246,-19],[-523,158],[-213,-41],[-340,-294],[-437,59],[-1088,19]],[[45741,82945],[304,-512],[196,-134],[107,-269],[554,-22],[1526,-193],[878,-73]],[[48830,86508],[-670,-56],[-431,68],[-679,-52],[-132,-284],[133,-139],[-540,-343],[-82,-431],[50,-518],[101,-148],[-154,-333],[500,-207],[-428,-845],[-757,-275]],[[57116,68580],[582,242],[502,79],[587,349],[-177,215],[322,608],[-1125,410],[284,301],[48,466],[438,377],[296,157],[234,383],[324,265],[334,86],[653,-140],[-72,130],[99,333],[-257,372],[-150,497],[508,145],[-167,49],[-234,351],[301,-183],[325,-86],[380,-286],[204,-68],[261,77],[141,-226],[399,-325],[531,-770],[669,-323],[661,-448],[497,-483],[387,-134],[365,-300],[312,-162],[200,-301],[442,-376]],[[45898,71811],[246,40],[808,-17],[413,-59],[537,-302],[337,-368],[71,-190],[572,60],[670,-260],[314,50],[356,-168],[819,-218],[703,9],[556,-91],[332,-193],[491,-65],[450,-194],[522,2],[883,-134],[55,-218],[239,-230],[657,-172],[454,-296],[285,-18],[448,-199]],[[41335,77620],[-106,-147],[135,-291],[17,-318],[-145,-220],[177,-127],[21,-222],[239,-252],[465,-79],[593,-421],[412,-80],[285,-163],[193,-261],[-13,-169],[245,-147],[437,-11],[1043,-245],[134,-611],[6,-356],[123,-165],[-44,-296],[257,-555],[-26,-234],[204,-329],[-89,-110]],[[57116,68580],[176,-657],[287,-404],[-192,-361],[416,-235],[1120,-196]],[[58923,66727],[637,51],[321,87],[805,85],[253,185],[411,156],[176,173],[889,402],[568,74],[1039,423],[71,158],[642,408],[198,238],[398,-371]],[[73049,66021],[-278,36],[-568,238],[-637,134],[38,84],[-1109,306],[-558,194],[-225,557]],[[66207,59969],[225,214],[38,260],[196,134],[73,549],[645,335],[441,30],[350,301],[136,404],[187,310],[286,217],[-10,174],[257,201],[102,216],[333,176],[2188,1506],[1395,1025]],[[58923,66727],[31,-224],[955,-771],[160,-357],[790,-281],[516,-64],[60,-417],[-187,-176],[173,-270],[-419,-253],[146,-178],[-741,-697],[-627,-348],[-3,-244],[-218,-188],[464,-538],[348,-172],[515,-15],[721,120],[488,-22],[603,-118],[120,-201],[443,-282],[259,-246],[453,-81],[362,-376],[78,-357],[-83,-320],[369,-29],[964,198],[544,149]],[[73061,66035],[534,533],[211,-15],[462,1301],[295,323],[-661,159],[-476,-10],[-500,415]],[[73049,66021],[12,14]],[[39274,80457],[228,-161],[1227,-177],[-66,-113],[246,-354],[260,-198],[124,-439],[268,-164],[462,-496]],[[45741,82945],[-513,-34],[-209,-210],[-337,291],[-105,-49],[-618,297],[-366,-278],[-624,-351],[-474,20],[-641,-235],[-309,-289],[-136,-354],[-214,-32],[-590,-275],[-283,-264],[-592,-235],[-78,-194],[-378,-296]],[[50891,91774],[-2972,776],[-388,-100],[-474,80],[-567,245],[-399,-191],[-452,-309],[-600,-15],[-235,150],[-1055,293],[-154,148],[-471,-278],[-242,-218],[-591,-254],[-731,125],[-274,144],[-553,44]],[[31853,82168],[432,-376],[594,-276],[324,-23],[303,-303],[535,-130],[356,-10],[163,-105],[1009,88],[222,75],[368,-22],[536,-130],[839,-345],[593,-309],[890,-108],[257,263]],[[54388,39523],[-688,760],[-155,100],[-1320,1068],[-1110,850],[-269,110]],[[48190,38030],[686,223],[798,167],[2789,274],[1283,429],[642,400]],[[40796,40035],[640,161],[172,292],[655,86],[894,341],[182,129],[236,-43],[1194,169],[282,-23],[776,100],[1427,-399],[-801,-349],[-16,-264],[1085,-1712],[668,-493]],[[43269,41118],[-972,-379],[-643,-149],[-641,-327],[-217,-228]],[[50846,42411],[-704,-531],[-950,-128],[-1326,-142],[-854,-195],[-873,-56],[-574,7],[-1875,-299],[-421,51]],[[57265,46314],[-533,774],[-582,248],[-1323,266],[-585,71],[-1324,-2]],[[58651,45117],[-397,183],[-342,57],[-295,245],[-405,93],[-54,433],[107,186]],[[52798,46915],[1116,-9],[788,-131],[637,-351],[596,-176],[117,-127],[-253,-61],[-168,-199],[45,-231],[413,-481],[-916,-198],[246,-288],[-85,-207],[189,-133],[787,225],[47,163],[474,188],[578,-84],[1282,30],[-40,272]],[[52918,47671],[71,-362],[-191,-394]],[[58690,44906],[0,0]],[[34745,36973],[-25,-84],[689,-438],[148,-237],[275,-141],[182,-398],[1263,-274],[356,-183],[629,214],[534,-10],[178,-97],[-129,-139],[174,-82],[43,-261],[547,-355],[464,-133],[465,59],[134,-102],[346,104],[2243,-564],[467,507],[808,1102],[1511,1072],[765,441]],[[40796,40035],[-464,193],[-498,-37],[-643,175],[-411,-151],[-1100,79],[-38,-221],[-441,-362],[-95,-375],[202,-675],[-711,-76],[-312,-394],[-530,-1025],[-1010,-193]],[[46812,36974],[-2055,757],[-927,521],[-203,75],[-1227,711],[-239,225],[-637,236],[-415,295],[-259,59],[-54,182]],[[46300,37963],[0,666],[-746,0],[0,-666],[746,0]],[[61506,42698],[890,30],[-1,235],[448,2],[18,897],[92,268],[705,-188],[462,-51]],[[60079,46477],[67,-297],[-75,-334],[-154,-211],[-203,-66],[-57,-325],[211,-365],[496,-218],[342,-49],[84,-123],[367,-105],[292,-182],[194,-475],[99,-6],[-236,-1023]],[[60926,47372],[-312,-162],[-535,-733]],[[63907,46365],[-679,298],[-130,-31],[-541,247],[-1392,271],[-239,222]],[[64425,44616],[-557,182],[219,60],[303,684],[-327,313],[-156,510]],[[64120,43891],[144,235],[-6,221],[167,269]],[[66689,43610],[-138,384],[-23,355],[-818,55],[-1285,212]],[[64120,43891],[2569,-281]],[[48723,44090],[631,-555],[491,-373],[1093,-683],[-92,-68]],[[48308,45292],[114,-279],[-128,-112],[-772,-95],[440,-184],[761,-532]],[[52675,46175],[-473,-68],[-315,119],[-446,23],[-565,-626],[-737,99],[-442,-19],[97,-154],[331,-189],[-715,-72],[-566,56],[-536,-52]],[[53320,43431],[-563,238],[-247,379],[-176,118],[-4,247],[262,463],[73,637],[-68,238],[78,424]],[[55544,42467],[-1308,529],[-513,168],[-403,267]],[[57589,41473],[-935,513],[-1110,481]],[[54388,39523],[645,184],[723,332],[964,718],[587,357],[282,359]],[[58103,41593],[1568,-591],[456,-228],[1104,-143],[1259,1],[523,-34],[-37,474],[1197,109],[2196,363],[1286,-51],[12,260],[215,103],[608,-380],[21,-207],[863,-51],[81,469]],[[61506,42698],[-748,-381],[-2655,-724]],[[69330,42128],[-692,-93],[-314,512],[194,122],[-33,352],[385,734],[-1151,-244],[-1030,99]],[[43913,43876],[-200,-336],[43,-339],[-260,-263],[119,-217],[-168,-195],[126,-92],[-390,-624],[-283,-311],[369,-381]],[[48723,44090],[-2179,26],[-264,241],[-674,-196],[-266,-149],[-695,-210],[-732,74]],[[57265,46314],[361,-129],[910,235],[18,249],[893,-68],[632,-124]],[[53602,50004],[289,-637],[-247,-125],[-245,-625],[-289,-127],[-61,-176],[-358,-464],[227,-179]],[[60926,47372],[-93,403],[177,108],[263,804],[-194,301],[78,180],[-457,388],[-182,-142],[-932,60],[-917,265],[-536,9],[-1015,247],[-767,349],[-565,48],[-816,-112],[9,-197],[-299,-104],[-512,-20],[-566,45]],[[52798,46915],[-24,-211],[-179,-3],[-11,-405],[91,-121]],[[57978,41615],[422,1419],[1124,479],[161,231],[27,400],[213,186],[-123,82],[-201,402],[-950,303]],[[57589,41473],[389,142]],[[54857,43958],[125,-101],[68,-328],[160,44],[106,-191],[94,-675],[134,-240]],[[52675,46175],[538,-275],[-7,-253],[199,-268],[547,-250],[63,-331],[243,-369],[367,-158],[232,-313]],[[54857,43958],[-307,-153],[-1230,-374]],[[46812,36974],[231,82],[282,281],[865,693]],[[57978,41615],[125,-22]],[[40234,45079],[-158,490],[106,446],[597,235],[85,100],[526,60],[285,206],[264,322],[20,195]],[[24605,43455],[329,824],[-360,190],[376,212],[994,-3],[137,-379],[630,-63],[315,314],[455,6],[259,-427],[448,123],[468,-389],[-40,-87],[2013,289],[383,112],[518,-16],[319,-101],[1465,78],[1259,294],[401,19],[392,191],[628,129],[1791,153],[1085,55],[1364,100]],[[10907,51654],[248,-318],[64,-702],[323,-415],[1135,-300],[1192,-2],[708,-137],[776,-265],[493,-114],[323,-214],[490,-153],[303,-210],[562,-118],[292,12],[235,152],[331,44],[208,-112],[651,-93],[478,-213],[36,-333],[277,-826],[213,-328],[15,-231],[234,-225],[303,-563],[649,-201],[1042,-494],[189,-589],[-116,-134],[563,-79],[676,-179],[55,-170],[750,-689]],[[24281,54558],[-511,-53],[-596,46],[-149,80],[-570,24],[-597,-517],[-697,-247],[-604,-16],[-38,-75],[-734,-66],[-544,23],[-428,-224],[-216,27],[-919,-218],[-797,228],[-733,-171],[-323,-334],[-171,-319],[-252,-57],[-627,40],[-1051,-159],[-578,-37],[-384,183],[-351,-48],[-168,-146],[0,-195],[-181,-56],[-1155,-617]],[[41959,47133],[71,509],[-736,198],[-314,442],[15,299],[-215,220],[-57,355],[-688,233],[-504,-107],[-1327,400],[-517,524],[-1441,-57],[-255,138],[-193,251],[-571,-231],[-592,-76],[-129,77],[-604,99],[-421,332],[-365,142],[-310,338],[-855,278],[-264,189],[60,453],[-139,486],[-316,531],[-599,198],[-286,-5],[-705,113],[-346,133],[-212,-23],[-747,275],[-568,66],[-456,-154],[-421,143],[-276,15],[-1870,417],[-525,224]],[[70600,50916],[-317,-762],[-188,-288],[-88,-364],[-378,-723],[-4,-279],[-159,-281],[-503,8],[-618,-306],[-356,34],[-557,-261],[-440,-22],[-836,-260],[-921,134],[-473,-128],[-355,-235],[-133,-699],[-367,-119]],[[66018,20671],[410,184],[562,-239],[669,-110]],[[65637,20844],[381,-173]],[[66158,21788],[-270,-385],[276,-122],[-527,-437]],[[68924,22710],[-166,53],[-231,-225],[-217,83],[485,473],[-477,296],[-402,426],[-336,134],[-25,-183],[-215,-238],[82,-175],[-441,-594],[-133,-99],[-356,-712],[-334,-161]],[[68178,20903],[214,400],[-65,150],[213,449],[-386,32],[202,434],[393,-27],[175,369]],[[67659,20506],[519,397]],[[62551,23890],[436,-300]],[[63367,25306],[-313,-313],[-212,-350],[107,-133],[-416,-405],[18,-215]],[[64864,25743],[-367,130],[-1004,-436],[-126,-131]],[[65190,23562],[1,480],[-329,903],[98,406],[-96,392]],[[63807,23071],[648,367],[735,124]],[[62987,23590],[546,-213],[274,-306]],[[77113,15261],[814,165],[-30,126],[248,53],[558,-90],[319,-141],[198,42],[415,-88],[475,105],[222,164],[435,-126],[607,-11],[281,69],[330,-73]],[[77230,17590],[230,-72],[90,-199],[-284,-313],[-26,-481],[73,-149],[-178,-893],[159,-26],[-181,-196]],[[77396,20148],[-129,-348],[0,-463],[175,-520],[231,-67],[-245,-362],[-40,-538],[-158,-260]],[[79158,18848],[-116,106],[82,430],[-139,137],[-376,67],[-448,172],[-349,50],[-416,338]],[[81985,15456],[191,93],[422,558],[-238,218],[-211,1194],[-616,218],[-1963,486],[-659,457],[-76,306],[323,-138]],[[54180,23523],[88,-178],[1198,-135],[737,-144],[852,-353],[346,57],[415,277],[95,194],[693,-60],[-10,-119]],[[57014,25186],[-994,-238],[-755,-219],[-182,-345],[-903,-861]],[[57850,24816],[-438,240],[-398,130]],[[58172,24566],[-135,-2],[-187,252]],[[58594,23062],[181,288],[-421,242],[-154,345],[536,137],[-370,384],[-194,108]],[[68856,27782],[459,-64],[842,65],[281,-84]],[[67737,30220],[519,-654],[111,-408],[470,-305],[-49,-812],[68,-259]],[[71016,29129],[-186,69],[-733,85],[-624,21],[-689,406],[-779,281],[-268,229]],[[70438,27699],[-13,712],[331,179],[260,539]],[[59205,23907],[-55,-230],[-176,-63],[41,-358],[-178,-87],[-111,-317]],[[61114,22956],[-269,59],[-47,241],[-999,350],[-209,209],[-385,92]],[[61043,20859],[668,162],[-53,373],[108,405],[-62,340],[-562,487],[-268,156],[240,174]],[[58726,22852],[-95,-243],[-343,-362],[96,-179],[571,190],[461,-50],[-102,-87],[100,-276],[415,28],[497,424],[460,90],[-20,-437],[249,-451],[-239,-245],[-45,-221],[312,-174]],[[58544,25364],[-370,-490],[-324,-58]],[[58172,24566],[219,198],[153,600]],[[67035,26688],[-213,-695],[273,-81],[61,217],[348,159],[177,-243],[-113,-578],[-99,-171],[80,-367],[-64,-121],[505,-127],[-148,-374],[-370,-253],[-262,71],[-171,-470],[-588,178],[-228,-715],[-129,-59],[-574,176],[-330,327]],[[68203,26887],[-709,141],[-459,-340]],[[70868,24728],[-289,93],[-1241,96],[-43,178],[-347,119],[89,400],[-77,186],[-430,464],[-62,289],[-265,334]],[[70974,24592],[-106,136]],[[69379,22677],[33,289],[320,391],[448,425],[382,461],[115,0],[297,349]],[[68924,22710],[455,-33]],[[63568,22267],[628,107],[204,-146],[789,-21],[385,-195],[480,12],[104,-236]],[[63807,23071],[-127,-234],[220,-66],[-399,-443],[67,-61]],[[74289,15419],[584,-720]],[[75025,17950],[-174,-486],[269,-261],[100,-608],[-259,-675],[-185,-226],[-487,-275]],[[77230,17590],[-917,20],[-37,138],[-1251,202]],[[75390,14403],[485,494],[569,216],[669,148]],[[74873,14699],[517,-296]],[[72827,14465],[-241,-234],[-440,-268],[-456,-566]],[[74289,15419],[-1008,-510],[-454,-444]],[[74087,11702],[441,427],[66,276],[-123,466],[83,574],[-114,191],[-313,150],[-260,287],[105,136],[901,490]],[[70308,11022],[1011,236],[544,-84],[429,210],[285,411],[707,-335],[628,115],[175,127]],[[69511,12099],[333,-504],[406,-413],[58,-160]],[[71690,13397],[-789,-544],[-188,-250],[-512,-327],[-690,-177]],[[67035,26688],[-355,-48],[-751,-493],[-392,195],[-688,-504],[15,-95]],[[70809,25841],[491,15],[483,242],[293,-121],[342,127]],[[70807,26402],[-64,-288],[66,-273]],[[72299,27037],[-763,47],[-234,-392],[-495,-290]],[[72418,26104],[-166,408],[47,525]],[[76454,27920],[-269,69],[-340,-35],[-145,112]],[[75800,25604],[273,73],[165,317],[348,86],[41,522],[-191,416],[154,500],[-136,402]],[[74921,26287],[179,-136],[624,-185],[76,-362]],[[75700,28066],[-6,-288],[150,-238],[-186,-292],[-517,-449],[85,-137],[-305,-375]],[[64745,19927],[-646,-674],[-924,-610],[-338,-108]],[[67075,18880],[-816,447],[-192,-42],[-561,213],[-761,429]],[[66768,17726],[-329,492],[543,427],[93,235]],[[66722,17127],[46,599]],[[62990,17878],[384,-527],[931,-251],[444,-285],[1135,130],[838,182]],[[62837,18535],[-107,-31],[260,-626]],[[73319,26071],[523,74],[700,-13],[379,155]],[[73676,27860],[-175,-800],[37,-376],[-204,-276],[-15,-337]],[[74657,28306],[-459,-175],[-116,-158],[-406,-113]],[[75700,28066],[-447,-7],[-169,156],[-427,91]],[[72344,27497],[-45,-460]],[[73676,27860],[-449,-51],[-61,-210],[-516,-168],[-306,66]],[[72954,25768],[365,303]],[[72418,26104],[536,-336]],[[61043,20859],[139,-310]],[[62987,23590],[186,-255],[-270,-490],[-302,8],[-365,-101],[-308,135],[-629,116],[-185,-47]],[[63516,21808],[52,459]],[[63627,21173],[-180,138],[-179,451],[248,46]],[[61182,20549],[624,207],[-92,268],[318,41],[752,211],[843,-103]],[[58594,23062],[132,-210]],[[59205,23907],[68,322],[-474,300],[-255,835]],[[70325,18094],[374,133],[79,-389],[-140,-406],[208,-88],[136,291],[354,197],[64,207],[192,111],[-144,218],[133,573],[-412,83]],[[71169,19024],[-315,37],[-529,-967]],[[70439,26865],[89,489],[-90,345]],[[68959,27064],[1085,-75],[395,-124]],[[68856,27782],[-223,5],[-30,-285],[257,-174],[99,-264]],[[71545,29085],[-529,44]],[[72344,27497],[73,439],[-119,-41],[-309,484],[-338,180],[23,515],[-129,11]],[[70439,26865],[418,-89],[-50,-374]],[[72440,24139],[-447,172],[-453,79]],[[73801,24307],[-64,-206],[183,-99],[-250,-298],[-306,-225],[99,-188],[-286,87],[-115,-106],[-484,-8],[-559,291],[-116,172],[537,412]],[[74223,25138],[-98,-212],[-377,-244],[193,-179],[-140,-196]],[[75800,25604],[-345,-243],[-300,-25],[-433,-320],[-499,122]],[[83023,33669],[129,-418],[-32,-219],[-339,-28],[-64,-243],[-657,61],[76,-363],[136,-213],[-473,-234],[-874,-121],[-662,-451],[-621,-58],[-607,-215],[-376,-68],[-326,-250],[-355,-57],[-217,-246],[-601,-509],[-131,-495],[170,-178],[-17,-297],[-376,-288],[117,-243],[-354,-373],[-115,-243]],[[83221,34582],[175,-441],[-373,-472]],[[86495,36376],[-1392,-65],[-838,-193],[-226,-134],[-190,-303],[-182,-468],[-288,-188],[-28,-255],[-277,-33],[147,-155]],[[89045,36968],[-273,131],[-1277,-269],[-1000,-454]],[[79158,18848],[175,110],[299,-109],[145,149],[20,380],[-116,88],[100,260],[-92,215],[737,-8],[157,-105],[770,165],[50,161],[302,141],[9,582],[236,108],[627,-127],[560,240],[38,395],[711,117],[-533,870],[-312,1974],[-525,433],[-386,181],[-111,180],[-741,410],[72,67],[-273,294],[150,220],[70,704],[922,727],[74,208],[-207,238],[149,370],[689,373],[382,-25],[534,128],[575,298],[671,413],[545,33],[321,87],[178,200],[287,103],[664,-19],[301,-164],[345,-9],[438,138],[487,9],[337,114],[465,-5],[401,200],[187,381],[-111,261],[72,688],[212,234],[370,128],[98,214],[662,767],[-53,537],[-1054,1472],[-231,574],[-209,299],[-553,585],[-200,468]],[[75503,19067],[200,286],[82,452],[266,535],[1308,-119],[37,-73]],[[71688,15160],[85,3],[523,959],[325,173],[321,515],[74,302],[143,132],[-91,366],[-12,517],[242,418],[232,132],[649,708],[-20,170],[1344,-488]],[[70028,15123],[985,-316],[444,462],[231,-109]],[[67321,15952],[712,-179],[159,-104],[938,-112],[272,-179],[626,-255]],[[66722,17127],[398,-514],[42,-481],[159,-180]],[[70325,18094],[-96,-177],[-380,-289],[-495,247],[61,-225],[-344,-179],[-337,69],[-94,-463],[-522,365],[-258,-53],[-33,185],[347,125],[-19,246],[-1387,-219]],[[72360,21541],[-96,-639],[-293,50],[-591,-72],[-556,-347],[-292,-294],[-21,-145],[254,-80],[379,-360],[25,-630]],[[70874,22103],[556,345],[18,375],[177,-40],[379,339],[-42,-248],[217,-47],[117,-310],[608,-236],[-272,-255],[135,-106],[-253,-50],[116,-221],[-270,-108]],[[69379,22677],[1174,-469],[108,-140],[213,35]],[[71540,24390],[-203,-17],[-363,219]],[[74639,20297],[-37,-98],[-431,-51],[-292,171],[-358,-13],[-237,253],[-536,54],[-54,189],[-288,-211],[-301,-46],[307,161],[197,330],[499,316],[556,210],[1732,-1],[648,-134],[246,-157],[-239,-928],[-1412,-45]],[[64731,19944],[14,-17]],[[66018,20671],[61,-97],[-474,-166],[-455,-17],[-102,-194],[-317,-253]],[[67075,18880],[558,1272],[26,354]],[[70868,24728],[-30,278],[138,450],[-167,385]],[[68959,27064],[79,-92],[-835,-85]],[[73801,24307],[-397,-1],[-458,-95],[-263,-155],[-243,83]],[[75025,17950],[120,381],[358,736]],[[71688,15160],[205,-223],[934,-472]],[[72721,33917],[-442,182],[-106,139],[-345,78],[-368,319],[-452,61],[27,495],[-75,103],[-803,-16],[-439,165],[-581,389],[-628,-77],[-657,-368],[-824,-2],[-804,73],[-494,-68],[-447,183],[-680,-138],[-595,-318],[1458,-1032],[-281,-85],[-125,-393],[959,-394],[335,26],[447,-229],[335,-335],[1261,-102],[514,-203],[180,206],[1850,126],[774,10],[402,196]],[[72117,32908],[604,1009]],[[65038,32256],[-178,316],[-359,410],[-755,163],[-227,114],[-987,-87]],[[64155,32240],[883,16]],[[62731,32483],[730,-32],[694,-211]],[[62532,33172],[23,-356],[176,-333]],[[58075,26273],[196,-267],[391,-175],[603,-128],[842,-339],[150,-134],[688,-184],[279,-336],[214,42],[542,-481],[229,-359],[342,-22]],[[58977,27457],[-339,-398],[-347,125],[-216,-911]],[[63367,25306],[-406,178],[-217,180],[-34,611],[-136,211],[-492,242],[-506,173],[-460,-41],[-313,95],[-421,246],[-753,202],[-652,54]],[[67321,15952],[79,-380],[-73,-316],[-551,-783],[-89,-384],[86,-379],[372,-488],[193,-162],[840,-456],[455,-517],[878,12]],[[71690,13397],[-735,286],[-656,-475],[-211,124],[-251,-253],[-421,98],[-80,324],[112,243],[-184,115],[279,303],[125,533],[360,428]],[[71279,21701],[263,333],[-270,116],[-427,-193],[29,146]],[[68178,20903],[455,26],[404,244],[504,209],[314,5],[521,327],[119,-190],[455,18],[329,159]],[[65637,20844],[-281,-205],[-190,37],[33,512],[-481,-122],[-816,263],[-160,129],[-54,293],[-172,57]],[[63627,21173],[-175,-150],[482,-82],[519,-462],[-128,-190],[406,-345]],[[58075,26273],[-123,-241],[-938,-846]],[[74657,28306],[-18,186],[-379,-59],[132,245],[-107,236],[-163,-32],[-128,251]],[[71766,29660],[51,-152],[-270,-214],[-2,-209]],[[73994,29133],[-518,43],[-514,106],[-243,127],[-474,-131],[-82,234],[-397,148]],[[89045,36968],[789,414]],[[82932,37791],[-67,-682],[64,-278],[521,-211],[578,6],[91,327],[292,98],[303,-96],[5,-184],[1062,-64],[313,159],[401,-490]],[[88373,39020],[-446,13],[-487,-316]],[[72062,30809],[-166,-337],[-498,-269],[381,-106],[-13,-437]],[[72071,30851],[-9,-42]],[[71447,31345],[364,-84],[271,-287],[-11,-123]],[[71396,31787],[131,-107],[-80,-335]],[[73994,29133],[80,404],[-169,550],[-351,172],[-892,337],[-119,599],[-174,280],[-160,-13],[-228,283],[-585,42]],[[72400,24682],[295,138],[606,112],[609,326],[252,22],[61,-142]],[[72954,25768],[-204,-204],[111,-170],[-469,-401],[8,-311]],[[61182,20549],[-68,-111],[241,-138],[62,105],[328,-261],[416,-433],[26,-243],[-144,-144],[91,-173],[515,-393],[188,-223]],[[72400,24682],[-722,-188],[-138,-104]],[[71279,21701],[575,-30],[506,-130]],[[77972,36479],[-436,-172],[-278,-222],[-767,-439],[-710,-209],[-182,-120],[-137,-384],[-489,-272],[-60,-175],[-521,-337],[-823,-324],[-628,421],[-209,-145],[-11,-184]],[[83023,33669],[-122,145],[280,315],[40,453]],[[72117,32908],[87,-369],[265,94],[-336,-260],[-693,-340],[-44,-246]],[[71447,31345],[94,-247],[304,-39],[226,-208]],[[72062,30809],[-1352,169],[-772,139],[-835,43],[-825,202],[-654,258],[-309,60],[-351,-135],[-453,-45],[-292,-126],[-572,122],[-242,411],[85,379],[-452,-30]],[[64155,32240],[162,-317],[353,-311],[309,-367],[303,-200],[475,-185],[1102,70],[581,-566],[297,-144]],[[61006,31400],[282,-865],[82,-858],[-1289,-1624],[-1246,337],[-215,-268],[-543,-335],[441,-100],[459,-230]],[[62731,32483],[-550,-291],[-356,-367],[-335,-459],[-484,34]],[[71508,39949],[-1854,21],[-915,62],[-976,205],[-720,37],[-428,-49],[-290,-352],[64,-186],[-248,-198],[58,-323],[-388,-510],[93,-243],[-555,-152],[-221,-249],[37,-165],[-436,-492],[-416,-585],[-355,-379],[-204,-425],[-147,-477],[-231,-519],[-690,-78],[224,-483],[1,-233],[-415,-858],[36,-146]],[[54180,23523],[-515,-513],[-702,-2068],[-161,-281],[635,-53],[198,131],[37,295],[388,10],[537,-101],[1023,-58],[300,-96],[459,147],[12,-72],[527,-281],[502,-87],[291,74],[467,-66],[417,97],[385,-328],[691,-139],[107,-303],[333,-19],[91,-438],[595,-341],[117,-182],[433,-204],[510,-362],[613,-333],[520,-74]],[[82961,13574],[204,780],[162,304],[-289,149],[-67,160],[-620,105],[-366,384]],[[82153,12567],[77,228],[-62,241],[253,332],[540,206]],[[77661,11676],[695,-147],[455,-236],[472,-40],[363,41],[552,-183],[744,486],[318,433],[278,29],[334,207],[281,301]],[[75390,14403],[187,-101],[310,-415],[929,-495],[301,-558],[196,-179],[253,-492],[-23,-283],[118,-204]],[[83592,2702],[-692,442],[-372,102],[-236,549],[-115,31],[287,282],[-137,128],[-282,15]],[[80977,2037],[2074,-277],[-203,117],[-54,266],[436,573],[166,-118],[196,104]],[[80028,3496],[515,-289],[454,-128],[347,-17],[-235,-548],[116,-27],[-248,-450]],[[80785,4373],[-238,-603],[-519,-274]],[[82045,4251],[-189,5],[-209,-172],[-360,256],[-502,33]],[[82045,4251],[304,462],[231,89]],[[78624,5093],[347,-157],[574,45],[183,-49],[218,141],[222,-231],[265,123],[420,-112],[-111,-258],[43,-222]],[[82153,12567],[537,-184],[-323,-89],[228,-213],[-48,-205],[-482,79],[-103,-90],[-460,-41],[-26,-119],[234,-292],[-74,-134],[372,-389],[28,-328],[210,-124],[-80,-243],[203,-249],[-378,-357],[-116,-236],[107,-217],[-59,-187],[164,-362],[-205,-737],[-47,-380],[-549,-309],[-413,-372],[-436,-207],[175,-148],[42,-287],[-221,8],[-249,194],[-216,-17],[-535,-266],[-198,-205],[11,-192],[-328,-199],[-461,-168],[167,-209]],[[84313,13363],[-434,264],[-461,32],[-457,-85]],[[82580,4802],[121,372],[259,44],[-54,127],[168,208],[658,442],[178,256],[227,112],[-208,298],[208,223],[-161,90],[306,91],[29,275],[251,12],[397,216],[-152,106],[-66,276],[212,16],[294,270],[47,406],[152,-26],[488,335],[-133,130],[206,135],[72,225],[-116,188],[27,322],[-667,-72],[-424,-154],[-891,-437],[-460,-32],[-149,342],[-20,359],[-310,170],[-31,162],[196,170],[-276,130],[-228,266],[-307,41],[145,127],[-233,121],[416,50],[-98,184],[466,228],[-105,361],[-384,280],[185,79],[-217,270],[140,197],[528,286],[360,-294],[345,252],[266,25],[76,301]],[[85358,2721],[-318,-95],[-1271,37]],[[80495,2016],[-545,-1421],[128,-143],[583,125],[304,-77],[315,-193],[613,-125],[201,23],[678,-179],[420,-9],[47,157],[375,169],[96,146],[502,5],[352,-144],[344,29],[340,312],[-406,141],[195,98],[8,279],[266,317],[-54,265],[156,60],[258,390],[-328,386],[15,94]],[[80977,2037],[-482,-21]],[[83769,2663],[-177,39]],[[76756,4785],[330,-218],[47,-354],[686,-219],[119,-159],[502,-366],[337,36],[-130,122],[183,247],[949,-250],[249,-128]],[[78624,5093],[-145,-65],[-706,65],[-206,70],[-63,-189],[-173,79],[-249,-257],[-326,-11]],[[72918,5502],[1987,-1050],[102,-99],[-344,-292],[140,-309],[-452,-68],[-177,-245],[178,-73],[-657,-116],[-20,-156],[273,-177]],[[70308,11022],[513,-400],[116,-588],[-311,-513],[241,-550],[408,-58],[565,-717],[143,-551],[99,-147],[-4,-631],[192,-378],[-89,-193],[478,-356],[585,371],[428,-408],[-221,-172],[-533,-229]],[[77661,11676],[48,-705],[-192,-187],[50,-126],[-30,-717],[-172,-346],[-169,-50],[-54,-226],[133,-427],[291,-242],[-508,-122],[-713,-339],[-412,426],[-140,317],[40,284],[-230,155],[-1,370],[-238,180],[-69,329],[-269,203],[-216,290],[-112,316],[-258,145],[-353,498]],[[75160,2802],[145,271],[701,374],[13,253],[-202,264],[484,290],[455,531]],[[73948,2917],[258,98],[563,-130],[393,136],[-2,-219]],[[85172,4402],[-441,147],[-543,76],[-306,-93],[-270,174],[-169,237],[-609,-180],[-254,39]],[[83769,2663],[438,434],[-51,167],[408,36],[10,172],[427,238],[-204,31],[-135,238],[255,125],[255,298]],[[75160,2802],[603,-207],[175,-137],[-114,-258],[362,-206],[374,-16],[408,-289],[310,96],[123,-79],[338,264],[-139,141],[149,114],[384,5],[289,-109],[669,354],[233,-57],[193,-329],[554,-120],[424,47]],[[72918,5502],[-865,-359],[-988,-1002],[-494,-445],[-806,-885],[-178,-523],[-49,-929],[789,390],[269,84],[427,-9],[399,-98],[278,21],[17,241],[193,27],[262,390],[434,110],[348,215],[183,-1],[811,188]],[[85358,2721],[41,169],[362,106],[-20,229],[271,332],[395,8],[193,372],[304,225],[377,107],[-256,111],[383,163],[-53,138]],[[87355,4681],[-545,-71],[-266,-194],[-414,-166],[-382,135],[-576,17]],[[87355,4681],[-277,353],[-19,571],[293,422],[245,186],[-91,186],[312,258],[-102,241],[369,210],[324,-36],[691,154],[99,-81],[557,596],[157,260],[431,141],[289,213],[-38,191],[219,212],[-278,263],[85,189],[475,-22],[294,201],[140,318],[466,121],[-184,294],[194,168],[-283,187],[-1261,-375],[-214,832],[228,384],[-106,273],[-437,170],[-466,-144],[2,-156],[-222,18],[72,260],[-283,160],[-473,77],[-461,206],[109,535],[-603,-91],[-190,61],[-612,-39],[38,205],[-585,362],[-319,275],[-735,-136],[-892,9]],[[73061,66035],[484,-577],[54,-299],[238,-391],[583,0],[525,-565],[1053,-1387],[334,-483],[736,264],[653,65],[524,-33],[806,287],[744,192],[-106,271],[264,236],[343,447],[134,46],[-25,304],[352,318],[445,129],[626,54],[615,-292],[555,3],[618,-75],[284,171],[929,218],[421,-98],[588,74],[308,-99],[1230,-137],[409,10]],[[87785,64688],[370,36],[516,365],[482,95],[218,197],[356,-39],[451,73],[10,386],[391,391],[122,252],[121,643],[-155,601],[23,393],[333,273],[-66,245],[-276,241],[-2,333],[-431,813],[-352,298]],[[86222,58823],[555,133],[349,381],[233,383],[146,68],[294,455],[485,149],[102,291],[202,238],[46,218],[-338,517],[-508,383],[-177,209],[-391,196],[5,307],[640,577],[-265,209],[-153,261],[381,598],[-43,292]],[[66207,59969],[400,-180],[259,2],[819,-348],[32,-340],[133,-130],[-354,-263],[-145,-532],[-144,-170],[-143,-840],[45,-303],[-58,-455],[59,-149],[323,-258],[118,-218],[383,-87],[233,-375],[-11,-664],[-129,-198],[132,-188],[62,-382],[477,-361],[623,-154],[308,35]],[[10719,63880],[-83,-296],[56,-331],[-88,-267],[271,-373],[-411,-315],[-206,-348],[-604,-148],[-13,-348],[-222,-136],[19,-254],[-1227,-178],[-344,-528],[123,-239],[-62,-436],[-259,-166],[-100,-212],[213,-363]],[[17851,62964],[-607,-49],[-473,347],[-1124,87],[-811,-160],[-545,161],[-180,-44],[-580,94],[-393,141],[-1444,10],[-975,329]],[[15536,59135],[709,20],[745,191],[452,-80],[344,119],[417,1038],[366,1298],[-125,333],[-593,910]],[[7782,58942],[921,-464],[492,36],[347,-63],[679,41],[272,-141],[763,269],[143,119],[552,-93],[1105,535],[364,73],[671,26],[406,-62],[278,-136],[630,-6],[131,59]],[[23330,56105],[-159,-118],[-803,-60],[-596,90],[-1208,617],[-1,669],[-563,402],[-365,11],[-371,162],[-405,363],[-596,262],[-319,-441],[-364,-53],[-974,497],[-1070,629]],[[24888,55662],[-479,19],[-710,217],[-369,207]],[[24281,54558],[210,169],[102,390],[295,545]],[[7782,58942],[-954,-243],[-605,-332],[-59,-154],[813,-790],[69,-502],[240,-251],[739,-549],[1005,-831],[804,-1292],[-330,-166],[-671,-223],[-4,-325],[-292,-81],[-259,-363],[-157,-38],[160,-488],[140,-157],[316,-110],[407,28],[1028,-217],[332,-187],[403,-17]],[[23330,56105],[-10,402],[255,187],[-59,424],[311,57],[-91,426]],[[22922,62471],[-391,56],[-615,392],[-754,366],[-202,228],[-354,63],[-203,136],[-367,83],[-190,-163],[-323,-61],[-195,-194],[-1173,-417],[-304,4]],[[23736,57601],[886,442],[290,376],[-70,270],[57,425],[-792,628],[-163,262],[-454,445],[-514,940],[-132,498],[146,70],[-68,514]],[[22922,62471],[688,-163],[625,48],[363,121],[1073,-1002],[282,-71],[493,-347],[321,-148],[-237,-561],[629,-396],[-345,-99],[413,-1166],[-435,-374],[50,-217],[-392,-480],[-253,-45],[-248,312],[-1023,-129],[-970,-185],[-220,32]],[[10167,76972],[78,-274],[-131,-231],[116,-167],[453,-91],[33,-228],[-178,-118],[-92,-291],[-592,-272],[-217,-281],[336,-488],[-114,-89],[203,-202],[-424,-361],[-58,-284],[258,-453],[538,-187],[332,-281],[370,-498],[-171,-315],[-316,-239],[-180,-271],[74,-263],[894,-693],[86,-135],[-517,-334],[-135,-232],[-463,-304],[-179,-298],[599,-546],[141,-241],[-41,-399],[174,-506],[-70,-498],[171,-193],[8,-246],[274,-306],[-12,-108],[-686,-416],[-15,-258],[-190,-89],[-179,-281],[181,-325],[33,-270],[179,-142],[-19,-388]],[[38439,61789],[-1823,804],[-98,117],[-1232,287],[-603,254],[-260,279],[-686,416],[-298,42],[-94,246],[-249,298],[-195,719],[-170,186],[-609,-221],[-435,-88],[-724,-17],[-641,-270],[-1239,367],[-622,626],[571,559],[94,185],[-52,483],[303,300],[130,317],[618,709],[-482,335],[-109,172],[-362,236],[-380,100],[-615,-237],[-665,-150],[-515,-63],[-529,69],[-453,325],[-775,381],[-638,181],[157,452],[-119,274],[178,553],[-218,166],[43,159],[-356,216],[89,139],[-459,231],[-755,163],[220,715],[-473,123],[-129,270],[-421,187],[-776,159],[-484,207],[90,410],[-681,817],[-94,22],[248,316],[21,305],[172,382],[315,397],[23,503],[-440,165],[-643,440],[-364,10],[-292,500],[-323,103],[-154,159],[84,216],[567,300],[144,284]],[[24888,55662],[243,156],[882,-51],[475,80],[247,187],[722,182],[772,913],[521,51],[173,248],[-168,73],[675,178],[609,422],[170,42],[946,477],[-8,536],[-792,688],[103,227],[548,231],[418,251],[-693,558],[524,-67],[793,-180],[1441,135],[477,202],[676,84],[709,-26],[475,-89],[283,35],[321,220],[61,202],[568,-9],[150,85],[1230,86]],[[50261,53818],[254,354],[-18,534],[168,222],[-541,397],[-317,378],[-409,303],[-97,174],[-473,-19],[-728,190],[-357,256],[-50,223],[93,302],[-259,180],[-482,168],[-881,424],[-159,4],[-533,307],[-14,190],[-400,287],[24,334],[-799,264],[-407,261],[-340,71],[-651,271],[-1048,39],[-375,222],[-795,155],[-1098,391],[-59,530],[-222,139],[-460,59],[-389,361]],[[46270,47145],[80,493],[-83,258],[234,324],[449,303],[-654,111],[98,352],[-1572,838],[520,610],[-157,68],[294,226],[371,134],[494,329],[183,215],[-602,409],[267,571],[886,855],[386,-109],[461,-39],[823,329],[275,-25],[778,450],[460,-29]],[[41959,47133],[1163,-123],[401,94],[704,-116],[599,21],[532,155],[438,-101],[474,82]],[[38439,61789],[260,546],[-14,125],[490,307],[433,131],[130,197],[-71,175],[277,436],[-123,425],[214,247],[21,271],[875,303],[425,265],[410,39],[573,192],[112,130],[-195,204],[-71,273],[384,75],[1334,793],[497,491],[-42,151],[419,451],[372,134],[-68,290],[41,404],[-281,327],[-227,142],[-111,247],[138,260],[-105,92],[330,383],[-33,223],[482,307],[152,356],[306,206],[-90,223],[215,201]],[[46270,47145],[245,-87],[-109,-250],[123,-267],[812,-430],[344,35],[163,-144],[45,-323],[249,1],[184,-147],[-18,-241]],[[53602,50004],[-371,442],[58,570],[198,353],[-196,91],[-193,348],[-518,384],[-631,-159],[-876,294],[-325,680],[-286,328],[-201,483]],[[40234,45079],[254,-144],[49,-238],[-164,-34],[92,-341],[399,-209],[75,-154],[570,62],[1166,69],[583,-52],[655,-162]],[[24605,43455],[316,-1224],[202,-319],[592,-320],[775,157],[484,-223],[-80,-110],[219,-121],[-120,-316],[182,47],[638,-147],[1071,-19],[114,-226],[-405,-4],[-42,-468],[-414,-123],[-494,-373],[-23,-366],[438,-62],[290,-247],[543,-243],[282,-370],[645,-284],[86,-107],[29,-453],[-57,-257],[253,-293],[-8,-266],[647,30],[358,-50],[214,84],[365,-11],[499,107],[348,-67],[1205,72],[751,135],[237,-45]],[[46812,36974],[1814,-2142],[123,-169],[453,-227],[874,-119],[783,-230],[298,-185],[948,-328],[1108,95],[1033,-5],[240,319],[364,266],[176,233],[1197,-473],[311,-368],[452,-121],[41,-248],[140,-3],[257,-280],[240,71],[860,-735],[515,-228],[714,-185],[664,-505],[589,-7]]],"transform":{"scale":[0.0032074926023382064,-0.004800048000480004],"translate":[319.6269736293908,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/ur.json b/src/onegov/election_day/static/mapdata/2025/ur.json new file mode 100644 index 0000000000..17775addce --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/ur.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":1201,"properties":{"id":1201,"name":"Altdorf (UR)"},"arcs":[[-1,-2,-3,-4]]},{"type":"Polygon","id":1202,"properties":{"id":1202,"name":"Andermatt"},"arcs":[[-5,-6,-7,-8]]},{"type":"Polygon","id":1203,"properties":{"id":1203,"name":"Attinghausen"},"arcs":[[-9,-10,-11,-12,-13,-14,-15,0]]},{"type":"Polygon","id":1205,"properties":{"id":1205,"name":"Bürglen (UR)"},"arcs":[[3,-16,-17,-18,-19,-20,-21,8]]},{"type":"Polygon","id":1206,"properties":{"id":1206,"name":"Erstfeld"},"arcs":[[-22,-23,-24,-25,10]]},{"type":"Polygon","id":1207,"properties":{"id":1207,"name":"Flüelen"},"arcs":[[-26,-27,-28,-29,15,2]]},{"type":"Polygon","id":1208,"properties":{"id":1208,"name":"Göschenen"},"arcs":[[-30,-31,-32,5,-33,-34]]},{"type":"Polygon","id":1209,"properties":{"id":1209,"name":"Gurtnellen"},"arcs":[[6,31,-35,23,-36,-37]]},{"type":"Polygon","id":1210,"properties":{"id":1210,"name":"Hospental"},"arcs":[[-38,-39,32,4]]},{"type":"Polygon","id":1211,"properties":{"id":1211,"name":"Isenthal"},"arcs":[[-40,-41,26,-42,13,-43]]},{"type":"Polygon","id":1212,"properties":{"id":1212,"name":"Realp"},"arcs":[[33,38,-44]]},{"type":"Polygon","id":1213,"properties":{"id":1213,"name":"Schattdorf"},"arcs":[[9,20,-45,-46,-47,21]]},{"type":"MultiPolygon","id":1214,"properties":{"id":1214,"name":"Seedorf (UR)"},"arcs":[[[14,41,25,1]],[[-48,27,40,-49]]]},{"type":"Polygon","id":1215,"properties":{"id":1215,"name":"Seelisberg"},"arcs":[[-50,-51,48,39]]},{"type":"Polygon","id":1216,"properties":{"id":1216,"name":"Silenen"},"arcs":[[35,22,46,-52,-53,-54]]},{"type":"Polygon","id":1217,"properties":{"id":1217,"name":"Sisikon"},"arcs":[[16,28,47,50,-55]]},{"type":"MultiPolygon","id":1218,"properties":{"id":1218,"name":"Spiringen"},"arcs":[[[52,-56,-57]],[[-58,44,19]]]},{"type":"Polygon","id":1219,"properties":{"id":1219,"name":"Unterschächen"},"arcs":[[-59,55,51,45,57,18]]},{"type":"Polygon","id":1220,"properties":{"id":1220,"name":"Wassen"},"arcs":[[24,34,30,-60,11]]}]}},"arcs":[[[40124,75364],[1374,-2754],[183,-302]],[[38501,78617],[469,-931],[250,-425],[201,-473],[703,-1424]],[[47776,79462],[-248,192],[-285,89],[71,201],[-853,93],[-317,193],[105,357],[-146,459],[-355,284],[-157,48],[156,334],[-210,233],[-408,-47],[-211,84],[-233,-62],[-230,260],[-321,-36],[-78,-245],[-335,56],[-114,224],[-610,-74],[-184,-509],[128,-182],[-54,-552],[-288,-14],[-559,-160],[-287,-260],[-110,1],[79,-323],[-145,-34],[-59,-312],[73,-133],[-316,-97],[-155,38],[-38,-312],[-188,-21],[-75,-193],[-111,438],[-194,19],[-109,-245],[-219,-58],[58,-210],[-489,-127],[-98,-225],[-86,163],[-336,-194],[-13,309],[-416,10],[-318,-107],[13,-198]],[[41681,72308],[437,349],[7,248],[555,340],[-7,191],[481,123],[-108,179],[314,157],[134,217],[623,243],[944,123],[28,288],[478,-85],[305,216],[152,290],[-143,111],[17,190],[-216,99],[245,200],[63,183],[-382,387],[-74,183],[220,215],[178,322],[190,838],[351,109],[-34,582],[-61,118],[476,484],[373,-3],[357,270],[192,-13]],[[27062,24093],[553,-35],[376,-117],[273,-216],[1477,-177],[1157,-811],[790,-379],[422,-275],[713,-143],[146,-346],[-149,-23],[240,-317],[28,-159],[616,-230],[304,-246],[154,-251],[116,-409],[266,-287],[2,-109],[264,-84],[229,-247],[3,-168],[243,-322],[120,-429],[-104,-104],[413,-294],[319,-371],[325,-159],[507,-475],[1212,-1369],[344,-570],[539,-389],[-201,-335],[-77,-420],[325,-292],[-107,-482],[-1,-291],[-225,-274],[52,-163],[448,-467],[183,-540],[271,-205]],[[44121,31755],[-148,-540],[22,-156],[-220,-320],[-232,-107],[-59,-200],[-713,-353],[-328,-67],[-452,-235],[-564,-776],[-237,-216],[-499,-165],[-172,-309],[-232,-220],[-249,-38],[-954,-434],[-328,-101],[-308,-240],[-448,-146],[-657,-377],[-282,-69],[-68,-241],[-375,-236],[-138,63],[-685,63],[-836,-128],[-505,334],[-644,-51],[-945,-456],[-620,67],[-447,141],[-592,117],[-375,-113],[-304,-565],[-23,-184],[-218,-179],[-372,-96],[-342,-170],[-330,21],[-298,-105],[-354,17],[-715,-144],[-265,-221],[-428,-191],[-120,-336]],[[49826,32432],[-1320,-274],[-76,-325],[-181,-144],[-233,-500],[-256,-33],[-1170,129],[-245,324],[-333,223],[-465,141],[-1084,76],[-325,-167],[-17,-127]],[[39628,11113],[505,-124],[477,123],[1118,-356],[51,-255],[203,-213],[298,-89],[-121,-474],[17,-161],[376,-1062],[104,-80],[444,-9],[139,-207],[1102,-40],[429,133],[51,139],[341,-44],[543,232],[529,113],[591,345],[264,36],[333,289],[302,567],[46,274],[521,46],[368,206],[92,202],[254,191],[751,201],[283,221],[821,39],[280,124],[535,2008],[-265,963],[1,431],[-615,683],[-105,234],[99,142],[-2,547],[381,512],[22,143],[-224,697],[-131,101],[77,1104],[75,319],[-390,846],[-222,-57],[-255,64],[-484,-96],[-643,96],[-686,331],[-31,309],[-240,62],[-291,227],[-311,87],[-240,261],[-1,512],[-305,344],[38,247],[-532,286],[-477,400],[133,719],[340,298],[343,94],[312,413],[-202,335],[202,383],[147,468],[-40,130],[-390,152],[-219,312],[1150,1311],[869,0],[949,642],[682,858],[570,305],[-281,816],[-573,551],[-107,414],[111,679],[-88,269]],[[41706,72276],[-25,32]],[[41514,68904],[118,759],[199,854],[59,424],[224,643],[-20,291],[-388,401]],[[21304,54265],[811,680],[182,215],[249,449],[-270,482],[186,268],[-99,249],[296,616],[95,516],[254,154],[24,375],[-84,267],[120,288],[-149,163],[228,320],[522,381],[146,177],[375,232],[523,530],[285,416],[323,307],[256,117],[221,359],[674,433],[-108,637],[132,461],[-17,432],[437,387],[315,216],[-127,180],[-18,431],[179,330],[-209,217],[-24,235],[-159,158],[-589,249],[1344,673],[354,137],[425,-69],[195,-125],[637,-141],[247,-1],[397,300],[334,1],[486,-147],[347,-260],[437,-2],[1033,-222],[846,86],[522,176],[247,1],[1507,626],[292,5],[235,-285],[650,-135],[307,-153],[418,230],[276,14],[131,-92],[577,-15],[344,205],[443,119],[359,171],[567,448],[279,154],[345,62],[381,544],[146,389],[122,18]],[[16643,52493],[654,315],[153,186],[440,347],[254,-108],[577,-97],[577,681],[409,186],[378,1],[453,-128],[87,201],[377,185],[302,3]],[[19161,68152],[-243,-130],[57,-450],[-153,-254],[-250,-211],[-498,-281],[-251,-25],[-395,-166],[-607,-178],[-458,-209],[-135,-201],[-251,-35],[-234,-556],[-230,-224],[4,-226],[-159,-389],[-348,-466],[-25,-264],[86,-185],[12,-685],[-82,-588],[-365,-306],[26,-285],[-272,-406],[-284,-141],[20,-232],[449,-266],[-3,-134],[469,-421],[14,-238],[-101,-201],[131,-212],[-19,-218],[-233,-311],[-588,-417],[-420,-116],[-715,-318],[-399,1],[-1052,232],[282,-388],[-195,-46],[391,-166],[257,-1],[556,-381],[222,-91],[517,303],[416,80],[594,271],[160,-969],[-474,-451],[-154,-363],[36,-183],[470,-350],[451,-277],[331,-643],[585,-494],[539,-1798]],[[27154,69338],[129,-396],[-333,-140],[-312,-236],[-298,-388],[-346,-119],[-104,-144],[-339,-178],[-133,-368],[-404,-109],[-544,-17],[-251,-154],[-413,226],[-245,-142],[-219,51],[-198,257],[-447,144],[-294,174],[-78,216],[-524,355],[-300,69],[-589,-147],[-401,179],[-174,-102],[-545,-63],[-209,-217],[-422,63]],[[40124,75364],[-640,-318],[-687,-72],[-807,0],[-863,179],[-383,-35],[-101,-168],[-244,-101],[-325,-454],[-223,-92],[-430,-419],[-217,-417],[-145,-73],[-287,-548],[-513,-349],[-265,-261],[-522,-140],[-119,-206],[-239,-82],[-629,-556],[-353,-210],[-255,-409],[-283,-221],[-323,-491],[-305,-212],[-475,-207],[-861,-456],[-633,-175],[-340,-234],[-69,-129],[-493,172],[-723,452],[-218,206]],[[50456,83991],[-394,-207],[-273,-227],[-70,-1058],[-263,-776],[-227,-232],[-267,-851],[-488,-349],[-698,-829]],[[54949,83948],[-91,-250],[-205,-265],[-296,-46],[-619,101],[-418,190],[-198,-84],[-237,183],[-270,-54],[-1281,187],[-127,129],[-169,-176],[-252,-27],[-330,155]],[[76406,85370],[238,100],[163,260],[-245,203],[48,317],[151,324],[70,528],[-47,244],[-211,259],[-278,173],[-82,440],[-1015,99],[-193,241],[-1062,251],[-638,597],[-344,-258],[-810,-430],[-168,2],[-940,-357],[-345,-278],[41,-164],[-321,-345],[-459,-306],[34,-198],[-755,-102],[-256,124],[-777,201],[-177,101],[-321,16],[-258,128],[-657,1090],[25,304],[-645,382],[-362,-248],[-406,-59],[-245,-301],[-529,-82],[-158,-148],[-338,-112],[-100,68],[-368,-285],[-96,77],[-1274,-642],[-720,320],[-2,-369],[-258,-244],[-270,-74],[-259,114],[-229,-177],[-284,148],[-125,-69],[-225,-413],[-371,-11],[-205,-106],[-307,-346],[-416,39],[30,-306],[-399,-253],[-177,37],[-149,-159],[26,-175],[-371,-279],[-131,-217],[-240,-64],[17,-296],[-201,-184],[-281,-82],[-29,-162],[-181,29],[-208,-120],[-514,107],[-680,-327],[-188,3]],[[67609,79913],[103,208],[207,81],[37,178],[-118,297],[183,263],[620,440],[440,236],[386,100],[106,112],[-146,395],[7,200],[330,336],[679,27],[1007,-182],[400,79],[567,-25],[576,151],[176,178],[64,427],[934,437],[450,286],[525,453],[1264,780]],[[56433,68997],[316,113],[50,459],[-29,361],[-279,477],[48,144],[-66,469],[-293,415],[-186,518],[-29,574],[-490,185],[-409,-159],[-232,183],[-674,268],[47,303],[-547,171],[-287,393],[60,95],[349,-83],[285,175],[190,218],[657,372],[76,103],[-48,700],[397,134],[82,-111],[517,155],[136,499],[637,1372],[-63,239],[190,322],[-300,1334],[51,158],[-202,484],[-29,616],[-106,232],[120,356],[-40,318],[144,225],[-97,1044],[143,258],[808,41],[683,-142],[-5,-711],[-160,-115],[288,-307],[30,-157],[328,-389],[-23,-91],[854,-669],[336,-226],[466,-112],[665,-219],[393,62],[166,-342],[733,-172],[312,-222],[1136,-470],[447,28],[319,-58],[225,48],[230,203],[546,10],[142,362],[654,291],[1514,184]],[[41706,72276],[363,18],[329,110],[2527,1406],[529,244],[419,248],[205,-239],[219,-70],[207,-301],[195,86],[241,-537],[611,-300],[407,-271],[760,-222],[115,21],[242,-191],[403,244],[302,19],[49,-226],[146,13],[55,-250],[480,-246],[96,-437],[181,-27],[62,-195],[191,-53],[50,205],[369,-59],[287,-450],[84,-329],[269,-95],[-87,-607],[334,-118],[95,53],[443,-68],[153,-239],[201,69],[192,-130],[314,56],[182,208],[328,-196],[369,78],[566,-94],[599,-162],[360,-211],[285,-34]],[[50688,65363],[148,387],[-26,191],[-187,60],[-251,253],[-729,12],[-332,84],[-230,196],[-327,21],[-566,-84],[-595,25],[-666,333],[-557,186],[-154,101],[-16,603],[-238,79],[-396,-48],[-582,42],[-448,194],[-351,295],[-155,34],[-124,-375],[-238,32],[-603,-247],[-399,1516],[-383,-124],[-322,-197],[-192,-14],[75,-268],[-198,-61],[-132,315]],[[47686,58599],[-551,777],[-116,388],[174,518],[-15,349],[-300,296],[551,1024],[322,165],[183,418],[171,-60],[184,174],[27,227],[314,286],[377,162],[425,109],[384,193],[122,419],[-57,117],[275,587],[-93,313],[352,350],[273,-48]],[[24752,53407],[208,158],[546,283],[260,77],[358,-15],[587,135],[234,296],[-5,125],[446,339],[137,13],[433,-303],[345,-65],[118,161],[360,230],[806,70],[687,-74],[306,-130],[498,73],[136,218],[267,92],[692,77],[293,-195],[569,-134],[224,165],[45,163],[467,211],[195,440],[-101,227],[239,129],[486,88],[256,112],[556,47],[536,330],[227,-84],[600,148],[601,-95],[471,70],[135,-38],[372,383],[526,-398],[490,-76],[381,17],[416,-319],[435,-19],[195,-513],[457,-69],[184,-133],[395,19],[381,216],[145,5],[680,452],[286,267],[695,461],[1151,293],[355,175],[604,214],[695,512],[873,361]],[[21304,54265],[498,-74],[884,-331],[331,-262],[309,-155],[635,178],[255,15],[439,-91],[97,-138]],[[37021,82533],[0,-918],[1268,-2540],[212,-458]],[[37021,83739],[0,-1206]],[[35337,86014],[1684,-2086],[0,-189]],[[50456,83991],[128,379],[-298,122],[-332,-6],[-586,184],[-223,-51],[-212,-176],[-835,167],[-282,198],[-235,306],[-113,273],[-902,126],[-534,332],[-405,12],[-376,119],[-244,154],[-602,44],[-295,144],[-205,-193],[-750,591],[-366,231],[-274,-20],[-1096,27],[-742,-178],[-600,-259],[-151,-252],[-138,34],[51,-241],[-133,-262],[-305,-11],[-43,-226],[210,-324],[-247,-184],[-625,95],[0,206],[-183,227],[55,310],[-382,125],[-2849,0]],[[10130,39208],[-68,-63],[0,-645],[-144,-251],[-113,-469],[32,-285],[227,-238],[61,-377],[241,-230],[-125,-117],[114,-179],[-204,-601],[-207,-386],[78,-326],[-103,-188],[-36,-385],[-624,-168],[-338,-135],[-427,-76],[-712,-332],[-513,162],[-803,118],[-298,-4],[-619,-184],[-813,131],[-133,83],[-544,54],[0,-80],[-465,74],[-460,7],[32,291],[-101,162],[-407,245],[-701,-52],[-1579,492],[-156,-264],[5,-582],[162,-148],[-151,-563],[-238,-295],[48,-380],[233,-167],[-68,-153],[104,-535],[-195,-643],[36,-268],[451,-359],[116,-438],[337,-496],[760,-282],[233,-249],[19,-300],[103,-208],[-5,-816],[109,-322],[-42,-251],[189,-817],[1436,-145],[111,-323],[304,-432],[278,-162],[-225,-280],[125,-445],[-92,-501],[15,-501],[-161,-296],[70,-273],[-267,-273],[100,-161],[-25,-237],[148,-199],[-28,-344],[208,-429],[29,-364],[237,-113]],[[42842,33652],[-2418,-890],[-849,-192],[-1889,-226],[-380,-147],[-1420,245],[-717,358],[-2238,-684],[-202,-86],[-414,87],[-294,154],[-866,270],[-1045,994],[-437,-117],[-1473,-84],[-264,63],[-573,-249],[-456,-58],[-519,217],[-667,143],[-355,-69],[-964,60],[-176,106],[-366,66],[-692,285],[-259,328],[-246,426],[-125,415],[-418,68],[-176,141],[-305,86],[-622,324],[-336,222],[-593,156],[-675,505],[-289,362],[-844,731],[-44,413],[-184,391],[-803,745],[-450,166],[-141,143],[-393,786],[-334,315],[-563,-110],[-344,-392],[-311,-191],[-342,-34],[-676,256],[-301,189],[-908,92],[-335,-72],[-601,-313],[-482,-192],[-227,-213],[-711,-433]],[[44121,31755],[-314,1012],[-310,123],[-458,387],[-197,375]],[[19098,20959],[-59,171],[342,38],[372,295],[38,372],[654,364],[454,315],[573,45],[83,-69],[612,130],[318,20],[488,-73],[302,-109],[308,7],[154,171],[326,174],[526,532],[470,46],[295,-41],[192,104],[249,316],[509,-6],[354,208],[404,124]],[[4691,21242],[496,-197],[832,-618],[301,-162],[241,-19],[551,-462],[405,-84],[776,150],[491,-65],[402,115],[372,40],[717,-34],[187,-93],[297,91],[371,204],[445,410],[738,113],[666,269],[381,-313],[506,-164],[134,-132],[450,-192],[140,51],[476,-369],[411,-125],[140,-147],[692,190],[344,205],[9,85],[819,330],[204,359],[486,53],[275,168],[427,-39],[225,99]],[[24752,53407],[641,-289],[55,-228],[-323,-112],[-90,-151],[-105,-489],[-151,-303],[19,-373],[550,-312],[301,-294],[193,-310],[-37,-284],[347,-321],[0,-348],[152,-119],[72,-339],[8,-746],[122,-196],[260,-73],[183,-211],[156,-383],[346,-251],[462,-139],[557,-225],[285,-282],[568,-282],[402,12],[463,-146],[323,15],[305,-84],[208,-180],[475,-185],[272,-686],[686,-680],[214,-79],[411,-310],[44,-162],[491,-91],[660,-943],[653,-658],[419,-138],[517,-90],[763,-378],[357,-306],[542,-250],[272,23],[442,-194],[113,-233],[495,-77],[306,-206],[381,92],[370,-30],[563,-195],[247,-27],[910,141],[436,-32],[429,-275],[476,78],[133,-121],[-68,-281],[239,-301],[-78,-560],[-271,-272],[-318,-635],[-6,-252],[137,-240],[-74,-492],[62,-225],[219,-311],[-160,-301],[263,-800],[-294,-489],[64,-142],[-70,-486],[96,-513]],[[53126,37787],[167,694],[-233,225],[-480,168],[-261,350],[-232,77],[-184,193],[-45,201],[-189,96],[-249,285],[228,226],[95,426],[-242,210],[63,310],[-72,499],[-299,41],[-162,275],[-455,486],[33,148],[445,366],[320,52],[205,227],[195,67],[-71,520],[-498,545],[-152,703],[-1199,907],[-91,134],[-294,53],[-590,398],[-138,40],[-436,456],[-417,145],[-35,175],[-408,173],[-427,-70],[-977,296],[-290,-13],[-636,292],[-734,169],[-110,422],[403,279],[104,552],[375,355],[292,95],[163,-51],[706,168],[247,294],[489,348],[65,370],[138,113],[771,210],[510,218],[259,456],[-205,720],[-292,273],[-262,431],[-10,536],[365,760],[-15,438],[-149,435],[-208,385],[-44,343],[66,329],[-353,1788]],[[49826,32432],[89,276],[-261,615],[65,233],[317,378],[3,263],[-245,632],[-34,571],[122,266],[347,448],[352,162],[412,27],[342,-139],[250,60],[437,-95],[536,434],[233,516],[160,520],[175,188]],[[25919,12799],[371,-263],[688,-318],[289,-330],[789,-370],[676,-3],[723,210],[299,-77],[221,97],[658,-58],[401,114],[896,416],[227,-3],[398,-315],[278,-124],[65,-208],[128,7],[378,-485],[166,-285],[564,-16],[604,-452],[498,-294],[508,21],[939,122],[222,-100],[297,22],[196,123],[373,1],[564,121],[503,48],[746,470],[44,243]],[[19098,20959],[332,-62],[125,-120],[318,-25],[338,-183],[25,-186],[224,-100],[907,-1004],[1432,-2153],[-150,-63],[-83,-329],[141,124],[694,239],[66,-31],[185,-603],[283,-385],[118,-364],[737,-1169],[105,-246],[285,-163],[615,-665],[124,-672]],[[27682,84774],[-225,96],[-98,324],[-183,323],[98,218],[-385,53],[-150,-64],[-369,30],[-310,108],[-524,14]],[[37021,83739],[-2194,0],[-474,241],[-392,-232],[-418,178],[-147,381],[102,309],[-458,291],[-255,-86],[-561,45],[-446,-227],[-264,-47],[-320,-385],[-239,-15],[-603,-314],[-492,-135],[-301,465],[-346,19],[-314,122],[-280,216],[-758,-1],[-179,210]],[[27154,69338],[544,337],[-231,297],[-11,220],[494,716],[63,237],[391,381],[13,509],[-109,194],[221,285],[121,400],[260,96],[383,388],[382,197],[464,340],[381,-27],[417,136],[95,346],[380,442],[-82,233],[419,406],[58,219],[-76,620],[130,260],[-177,-61],[-711,51],[-441,321],[-52,183],[-577,76],[284,299],[-201,265],[216,722],[242,231],[305,126],[-172,436],[-549,199],[988,839],[279,334],[371,251],[-96,203],[628,248],[457,431],[607,317],[233,205],[-196,452],[92,49],[270,-226],[340,-61],[240,73],[2780,0]],[[25536,85876],[-528,-316],[-698,-175],[-217,-143],[-271,-22],[-484,-295],[-411,24],[-90,-86],[-706,-32],[-239,-94],[-682,14],[-169,-607],[-502,-222],[-121,-221],[-245,-24],[-546,-256],[-337,-223],[-559,-108],[-551,-175],[-144,40],[-189,265],[-215,145],[-305,468],[-381,-190],[-280,-3],[-150,138],[-211,-36],[-1134,6],[-194,-282],[-54,-739],[-83,-377],[-382,-446],[-119,-295],[-677,-234],[-498,-70],[-69,-65],[-646,-206],[-522,-235],[-214,88],[-411,-124],[-169,-435],[-478,-384],[-147,-238],[-256,-231],[215,-247],[325,-86],[1144,90],[481,-479],[37,-136],[645,-257],[-189,-421],[340,-476],[336,-197],[63,-457],[392,-776],[-924,-614],[-363,-391],[-706,-170],[-122,-193],[8,-396],[110,-213],[441,-526],[6,-364],[207,-232],[-380,-866],[37,-448],[-249,-296],[232,-308],[-13,-250],[332,-359],[-2,-319],[670,-58],[312,109],[201,333],[462,148],[420,-389],[463,-49],[316,-247],[638,-197],[554,-58],[331,45],[491,176],[118,-317],[335,-232],[330,-347],[80,-324],[510,-418],[275,-111]],[[4691,21242],[-287,-210],[-68,-266],[57,-220],[-20,-503],[96,-428],[-106,-143],[53,-309],[-41,-263],[-341,-352],[-265,-465],[46,-657],[-179,-573],[-183,-89],[-172,-363],[-151,5],[-404,-353],[-93,-203],[-412,-180],[-96,-399],[307,-426],[188,-132],[-233,-323],[-35,-484],[-120,-327],[-110,-840],[-222,-375],[335,-306],[-52,-321],[520,-710],[-116,-200],[28,-273],[443,-422],[508,-588],[348,-344],[408,-918],[100,-134],[-100,-227],[85,-328],[376,-603],[247,-74],[76,-154],[-59,-784],[166,-504],[-6,-224],[150,-328],[151,-62],[202,-463],[-41,-273],[395,-401],[6,-246],[145,-207],[652,-74],[255,-249],[242,-346],[480,-96],[174,105],[346,-87],[426,-343],[259,-111],[83,-156],[1180,-351],[546,-190],[377,-41],[234,-96],[571,156],[420,344],[335,-73],[289,-383],[166,41],[774,-733],[236,-393],[749,-194],[552,367],[334,667],[440,-13],[266,98],[867,71],[664,331],[449,-69],[412,4],[272,199],[738,21],[379,142],[69,99],[1465,566],[613,22],[-46,482],[207,287],[-285,261],[-218,310],[61,331],[-276,162],[-156,236],[-239,622],[245,634],[-104,231],[-323,226],[-84,310],[184,437],[286,463],[174,142],[238,544],[512,323],[-10,673],[-198,555],[342,415],[-11,301],[-129,270],[690,132],[-30,298],[222,232],[33,265],[246,219],[440,255],[215,188],[516,-1],[403,83],[485,408]],[[56129,68233],[-55,162],[390,243],[-146,225],[115,134]],[[54785,65463],[229,266],[122,300],[-21,205],[929,-126],[137,295],[-89,178],[311,405],[5,139],[-407,732],[128,376]],[[50688,65363],[391,-137],[1031,-166],[367,-21],[869,269],[189,153],[257,-52],[99,85],[402,17],[251,-99],[241,51]],[[35337,86014],[-611,756],[897,2559]],[[35623,89329],[-2856,-1],[-250,49],[77,-291],[-211,-66],[-532,17],[-501,-110],[-161,88],[-410,-471],[-485,121],[-20,-295],[-157,-478],[-805,-45],[-264,64],[-194,-97],[-402,37],[-600,160],[-128,-92],[137,-330],[1077,-577],[-40,-305],[132,-215],[-259,-258],[-179,-595],[-463,-322],[-52,-189],[-395,-354]],[[36267,91168],[-224,3552],[-443,1426],[502,1527],[-195,963],[-1089,710],[-2650,653],[-2026,-721],[601,-1349],[124,-163],[-384,-646],[-150,-76],[-239,-308],[-355,-592],[-253,-200],[-861,-376],[161,-578],[-273,-459],[-215,-540],[-195,-59],[-115,-249],[-625,-210],[44,-425],[181,-283],[-79,-723],[46,-541],[-28,-550],[318,-835],[-275,-414],[237,-48],[-163,-222],[55,-122],[-145,-350],[56,-291],[412,40],[54,-218],[-462,-154],[-38,196],[-229,-194],[-818,8],[-166,-153],[-812,169],[203,-653],[118,-153],[197,44],[91,-227],[-133,-313],[102,-194],[-546,-596],[-90,-163],[43,-232]],[[35623,89329],[644,1839]],[[80789,67950],[-452,-382],[-402,-217],[5,-284],[-192,-162],[-490,-1121],[-439,-493],[-556,-490],[-856,1],[-247,146],[-561,156],[21,87],[-401,78],[-258,-225],[-362,9],[-343,132],[-387,40],[-205,-159],[-346,-83],[-587,-339],[-324,-236],[-1234,-212],[-474,-227],[-246,-312],[-684,38],[-136,-227],[-190,-83],[-433,-499],[-98,-194],[-398,-273],[-15,-113],[-471,-155],[-33,-112],[-391,-275],[-112,-326],[-1050,-244],[-431,-57],[-294,-110],[-199,50],[-644,-158],[-171,-292],[-538,-17],[-523,-137],[-786,-40],[-412,170],[-446,92],[-294,0],[-823,371],[-121,230],[-513,166],[-521,-71],[-53,487],[89,369],[-117,358],[-377,23],[-286,123],[-301,20],[-490,-222],[-1064,-5],[-1548,576],[-285,38],[-356,147],[-118,192],[-224,84],[-495,343],[-81,411],[304,808],[-307,323],[-232,-3]],[[84635,68267],[-953,187],[-455,-132],[-392,-183],[-399,-17],[-257,-215],[-191,-14],[-338,234],[-315,136],[-546,-313]],[[53126,37787],[526,219],[544,145],[466,-12],[526,-272],[165,-244],[739,-415],[193,266],[216,16],[687,287],[368,227],[80,312],[-3,438],[434,186],[773,-43],[573,172],[366,273],[314,399],[304,286],[764,484],[594,125],[393,332],[479,218],[324,275],[266,509],[-1,254],[-126,120],[-749,1359],[182,568],[-67,42],[374,342],[114,407],[-50,154],[359,114],[244,242],[347,135],[562,558],[488,244],[376,245],[910,409],[628,-85],[-146,-190],[127,-82],[62,-279],[-61,-177],[139,-133],[473,-114],[143,-437],[393,-382],[-25,-184],[189,-128],[-30,-128],[190,-342],[575,-210],[274,-618],[605,240],[128,98],[563,121],[514,221],[472,82],[763,15],[98,-60],[716,554],[573,237],[323,13],[340,271],[444,216],[-352,921],[-141,702],[646,1093],[-92,609],[135,524],[274,404],[212,199],[226,80],[62,324],[-139,391],[55,159],[721,251],[70,223],[429,305],[934,-323],[206,-26],[503,548],[-309,400],[-260,166],[-209,343],[6,464],[-85,133],[-30,378],[-116,310],[-205,303],[-37,337],[191,361],[-35,365],[-210,565],[-229,222],[-58,236],[154,253],[78,455],[81,109],[456,104],[424,305],[161,227],[406,53],[429,-23],[444,-292],[1282,-43],[-233,645],[47,331],[358,177],[577,198],[400,356],[75,136],[405,280],[-16,157],[428,376],[544,74],[563,164],[610,-7],[333,281],[514,211],[217,525],[270,345],[-281,649],[118,210],[689,683],[221,1930],[-837,932],[-499,363],[34,332],[-177,400],[69,218],[-203,365],[-319,139]],[[54949,83948],[-344,514],[-376,334],[-776,378],[-170,246],[-179,614],[-219,380],[662,834],[-101,460],[-396,820],[-207,350],[51,406],[-93,181],[-294,136],[-127,154],[-213,545],[-510,17],[-1036,-365],[-565,139],[-733,-109],[-307,-163],[-308,14],[-512,-199],[-344,16],[-678,281],[-556,27],[-568,144],[-342,-124],[-180,122],[-351,56],[-1041,262],[-451,199],[-497,63],[-238,-35],[-149,101],[-494,-35],[-244,72],[-590,-35],[-755,95],[-329,-82],[-20,219],[-643,347],[-525,-7],[-2934,-152]],[[81265,77485],[66,-206],[454,-447],[529,-172],[-284,-259],[-471,-316],[-260,-49],[-406,52],[-241,-91],[-297,-238],[637,-283],[562,-423],[-97,-495],[100,-526],[196,-365],[323,-1149],[15,-157],[310,-523],[-188,-171],[-307,-117],[-231,-284],[-368,-85],[-154,-214],[-179,-41],[-473,-321],[-103,-298],[240,-431],[351,-887],[20,-359],[-298,-379],[78,-301]],[[84635,68267],[406,83],[315,282],[438,97],[332,202],[222,37],[558,227],[863,452],[555,65],[208,115],[456,121],[204,303],[414,336],[201,343],[-35,82],[461,358],[168,224],[406,333],[271,335],[327,169],[334,-142],[830,-14],[344,70],[940,619],[632,209],[749,177],[118,95],[332,-15],[443,482],[292,127],[545,404],[189,200],[646,118],[96,160],[285,44],[185,140],[332,52],[984,477],[318,898],[-219,1458],[82,341],[-517,1400],[-91,539],[-246,287],[95,502],[-293,194],[-578,-11],[-309,227],[-218,481],[-396,253],[-237,758],[-457,537],[-844,1615],[-338,-117],[-270,-227],[-314,-100],[-976,-564],[-332,81],[-364,-379],[-224,22],[-407,-280],[-53,-154],[-343,-218],[-159,102],[-492,-187],[-13,-124],[-279,-314],[-399,28],[14,-298],[-386,202],[-424,-52],[-740,-417],[41,-345],[-529,-52],[-142,-344],[-335,-38],[-420,65],[-275,-127],[-440,-44],[-617,-344],[-168,-369],[-261,-260],[-1170,-642],[-544,-110],[-47,-101],[-465,32],[-550,180],[-653,-85],[55,-206],[-192,-156],[41,-273],[-136,-277],[-325,-281],[-470,-152],[-255,-311],[55,-289],[-205,-103]],[[56129,68233],[555,44],[574,-427],[949,-71],[1083,187],[237,338],[450,796],[417,96],[148,192],[516,325],[-44,105],[456,199],[661,-206],[519,124],[155,396],[92,46],[646,1223],[227,1058],[-485,164],[482,631],[20,252],[-113,138],[98,392],[-155,282],[134,242],[699,377],[290,270],[225,70],[179,425],[246,325],[601,506],[592,745],[880,545],[878,1289],[-403,380],[-244,81],[-85,141]],[[81265,77485],[-78,25],[-655,594],[-330,589],[-21,420],[117,522],[106,1014],[-186,486],[60,249],[-71,360],[190,738],[-7,530],[-116,349],[-317,211],[-156,-360],[-347,-169],[-264,-408],[-546,-248],[-623,-150],[-166,439],[-332,361],[-619,1123],[-263,253],[-170,301],[-65,656]],[[16643,52493],[-498,-305],[-752,-129],[-270,-270],[-501,-164],[-229,35],[-855,-232],[-615,29],[-320,280],[-455,83],[-327,-11],[-319,-219],[-439,109],[-759,-398],[-23,-166],[-296,-98],[-1068,-578],[-132,-442],[-94,-537],[93,-104],[-219,-302],[-385,-335],[-88,-333],[-427,73],[-360,-243],[97,-376],[392,-284],[358,-622],[-531,-549],[-89,-413],[170,-71],[-73,-708],[32,-242],[210,-466],[315,-297],[576,-270],[328,-344],[191,-327],[-69,-222],[-333,-119],[-64,-259],[52,-1993],[73,-278],[-51,-330],[162,-423],[154,-155],[374,-166],[551,-114]]],"transform":{"scale":[0.003927073319547581,-0.004800048000480004],"translate":[283.6482975592807,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/vd.json b/src/onegov/election_day/static/mapdata/2025/vd.json new file mode 100644 index 0000000000..501141e295 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/vd.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":5401,"properties":{"id":5401,"name":"Aigle"},"arcs":[[-1,-2,-3,-4,-5]]},{"type":"Polygon","id":5402,"properties":{"id":5402,"name":"Bex"},"arcs":[[-6,-7,-8,-9,-10,-11]]},{"type":"Polygon","id":5403,"properties":{"id":5403,"name":"Chessel"},"arcs":[[-12,-13,-14,-15]]},{"type":"Polygon","id":5404,"properties":{"id":5404,"name":"Corbeyrier"},"arcs":[[-16,-17,-18,-19,-20]]},{"type":"Polygon","id":5405,"properties":{"id":5405,"name":"Gryon"},"arcs":[[8,-21,-22]]},{"type":"Polygon","id":5406,"properties":{"id":5406,"name":"Lavey-Morcles"},"arcs":[[-23,5]]},{"type":"Polygon","id":5407,"properties":{"id":5407,"name":"Leysin"},"arcs":[[19,-24,1,-25]]},{"type":"Polygon","id":5408,"properties":{"id":5408,"name":"Noville"},"arcs":[[-26,-27,-28,-29,-30,-31,13,-32]]},{"type":"Polygon","id":5409,"properties":{"id":5409,"name":"Ollon"},"arcs":[[-33,3,-34,-35,20,7]]},{"type":"Polygon","id":5410,"properties":{"id":5410,"name":"Ormont-Dessous"},"arcs":[[33,2,23,18,-36,-37,-38]]},{"type":"Polygon","id":5411,"properties":{"id":5411,"name":"Ormont-Dessus"},"arcs":[[9,21,34,37,-39,-40]]},{"type":"Polygon","id":5412,"properties":{"id":5412,"name":"Rennaz"},"arcs":[[29,-41,-42]]},{"type":"Polygon","id":5413,"properties":{"id":5413,"name":"Roche (VD)"},"arcs":[[41,-43,16,-44,14,30]]},{"type":"Polygon","id":5414,"properties":{"id":5414,"name":"Villeneuve (VD)"},"arcs":[[-45,-46,-47,35,17,42,40,28]]},{"type":"Polygon","id":5415,"properties":{"id":5415,"name":"Yvorne"},"arcs":[[24,0,-48,11,43,15]]},{"type":"Polygon","id":5422,"properties":{"id":5422,"name":"Aubonne"},"arcs":[[-49,-50,-51,-52,-53,-54,-55,-56,-57,-58]]},{"type":"Polygon","id":5423,"properties":{"id":5423,"name":"Ballens"},"arcs":[[-59,-60,-61,-62,-63]]},{"type":"Polygon","id":5424,"properties":{"id":5424,"name":"Berolle"},"arcs":[[59,-64,-65,-66,-67]]},{"type":"Polygon","id":5425,"properties":{"id":5425,"name":"Bière"},"arcs":[[57,-68,-69,-70,63,58,-71,-72]]},{"type":"Polygon","id":5426,"properties":{"id":5426,"name":"Bougy-Villars"},"arcs":[[53,-73,-74,-75,-76]]},{"type":"Polygon","id":5427,"properties":{"id":5427,"name":"Féchy"},"arcs":[[-77,72,52,-78]]},{"type":"Polygon","id":5428,"properties":{"id":5428,"name":"Gimel"},"arcs":[[-79,-80,-81,-82,68,-83,55,-84]]},{"type":"Polygon","id":5429,"properties":{"id":5429,"name":"Longirod"},"arcs":[[-85,-86,-87,79,-88,-89]]},{"type":"Polygon","id":5430,"properties":{"id":5430,"name":"Marchissy"},"arcs":[[-90,-91,-92,-93,84]]},{"type":"Polygon","id":5431,"properties":{"id":5431,"name":"Mollens (VD)"},"arcs":[[66,-94,-95,60]]},{"type":"Polygon","id":5434,"properties":{"id":5434,"name":"Saint-George"},"arcs":[[80,86,-96]]},{"type":"Polygon","id":5435,"properties":{"id":5435,"name":"Saint-Livres"},"arcs":[[71,-97,-98,48]]},{"type":"Polygon","id":5436,"properties":{"id":5436,"name":"Saint-Oyens"},"arcs":[[-99,-100,87,78]]},{"type":"Polygon","id":5437,"properties":{"id":5437,"name":"Saubraz"},"arcs":[[67,56,82]]},{"type":"Polygon","id":5451,"properties":{"id":5451,"name":"Avenches"},"arcs":[[-101,-102,-103]]},{"type":"Polygon","id":5456,"properties":{"id":5456,"name":"Cudrefin"},"arcs":[[-104,-105]]},{"type":"Polygon","id":5458,"properties":{"id":5458,"name":"Faoug"},"arcs":[[101,-106]]},{"type":"Polygon","id":5464,"properties":{"id":5464,"name":"Vully-les-Lacs"},"arcs":[[-107,100,-108,103]]},{"type":"Polygon","id":5471,"properties":{"id":5471,"name":"Bettens"},"arcs":[[-109,-110,-111,-112,-113,-114]]},{"type":"Polygon","id":5472,"properties":{"id":5472,"name":"Bournens"},"arcs":[[-115,-116,109,-117,-118]]},{"type":"Polygon","id":5473,"properties":{"id":5473,"name":"Boussens"},"arcs":[[-119,-120,-121,-122,116,108]]},{"type":"Polygon","id":5474,"properties":{"id":5474,"name":"La Chaux (Cossonay)"},"arcs":[[-123,-124,-125,-126,-127,-128,-129,-130]]},{"type":"Polygon","id":5475,"properties":{"id":5475,"name":"Chavannes-le-Veyron"},"arcs":[[-131,-132,-133,-134,125]]},{"type":"Polygon","id":5476,"properties":{"id":5476,"name":"Chevilly"},"arcs":[[-135,-136,-137,-138,128]]},{"type":"Polygon","id":5477,"properties":{"id":5477,"name":"Cossonay"},"arcs":[[-139,-140,122,-141,-142,-143]]},{"type":"Polygon","id":5479,"properties":{"id":5479,"name":"Cuarnens"},"arcs":[[-144,126,133,-145,-146]]},{"type":"Polygon","id":5480,"properties":{"id":5480,"name":"Daillens"},"arcs":[[-147,-148,-149,110,115,-150,-151]]},{"type":"Polygon","id":5481,"properties":{"id":5481,"name":"Dizy"},"arcs":[[-152,140,129,137,-153]]},{"type":"Polygon","id":5482,"properties":{"id":5482,"name":"Eclépens"},"arcs":[[147,-154,-155,-156,-157,-158]]},{"type":"Polygon","id":5483,"properties":{"id":5483,"name":"Ferreyres"},"arcs":[[-159,135,-160,-161,-162]]},{"type":"Polygon","id":5484,"properties":{"id":5484,"name":"Gollion"},"arcs":[[-163,-164,-165,-166,-167,-168,138]]},{"type":"Polygon","id":5485,"properties":{"id":5485,"name":"Grancy"},"arcs":[[124,-169,-170,-171,130]]},{"type":"Polygon","id":5486,"properties":{"id":5486,"name":"L'Isle"},"arcs":[[-172,-173,144,132,-174,-175,-176]]},{"type":"Polygon","id":5487,"properties":{"id":5487,"name":"Lussery-Villars"},"arcs":[[-177,141,151,-178,153,146]]},{"type":"Polygon","id":5488,"properties":{"id":5488,"name":"Mauraz"},"arcs":[[174,-179,-180]]},{"type":"Polygon","id":5489,"properties":{"id":5489,"name":"Mex (VD)"},"arcs":[[-181,-182,-183,-184]]},{"type":"Polygon","id":5490,"properties":{"id":5490,"name":"Moiry"},"arcs":[[159,134,127,143,-185,-186,-187,-188,-189]]},{"type":"Polygon","id":5491,"properties":{"id":5491,"name":"Mont-la-Ville"},"arcs":[[-190,-191,-192,184,145,172,-193]]},{"type":"Polygon","id":5492,"properties":{"id":5492,"name":"Montricher"},"arcs":[[175,179,-194,93,65,-195,-196]]},{"type":"Polygon","id":5493,"properties":{"id":5493,"name":"Orny"},"arcs":[[-197,-198,155,-199]]},{"type":"Polygon","id":5495,"properties":{"id":5495,"name":"Penthalaz"},"arcs":[[142,176,150,-200,162]]},{"type":"Polygon","id":5496,"properties":{"id":5496,"name":"Penthaz"},"arcs":[[-201,-202,163,199,149,114]]},{"type":"Polygon","id":5497,"properties":{"id":5497,"name":"Pompaples"},"arcs":[[-203,196,-204,-205]]},{"type":"Polygon","id":5498,"properties":{"id":5498,"name":"La Sarraz"},"arcs":[[-206,-207,203,198,154,177,152,136,158,-208]]},{"type":"Polygon","id":5499,"properties":{"id":5499,"name":"Senarclens"},"arcs":[[139,167,-209,168,123]]},{"type":"Polygon","id":5501,"properties":{"id":5501,"name":"Sullens"},"arcs":[[117,121,-210,-211,183,-212,200]]},{"type":"Polygon","id":5503,"properties":{"id":5503,"name":"Vufflens-la-Ville"},"arcs":[[211,182,-213,-214,-215,164,201]]},{"type":"Polygon","id":5511,"properties":{"id":5511,"name":"Assens"},"arcs":[[113,-216,-217,-218,-219,-220,-221,118]]},{"type":"Polygon","id":5512,"properties":{"id":5512,"name":"Bercher"},"arcs":[[-222,-223,-224,-225,-226,-227]]},{"type":"Polygon","id":5514,"properties":{"id":5514,"name":"Bottens"},"arcs":[[-228,-229,-230,217,-231,-232,-233]]},{"type":"Polygon","id":5515,"properties":{"id":5515,"name":"Bretigny-sur-Morrens"},"arcs":[[-234,218,229,-235,-236]]},{"type":"Polygon","id":5516,"properties":{"id":5516,"name":"Cugy (VD)"},"arcs":[[235,-237,-238,-239,-240]]},{"type":"Polygon","id":5518,"properties":{"id":5518,"name":"Echallens"},"arcs":[[-241,-242,-243,230,216,-244]]},{"type":"Polygon","id":5520,"properties":{"id":5520,"name":"Essertines-sur-Yverdon"},"arcs":[[-245,-246,-247,-248,-249,-250,-251,-252,-253]]},{"type":"Polygon","id":5521,"properties":{"id":5521,"name":"Etagnières"},"arcs":[[119,220,-254,-255]]},{"type":"Polygon","id":5522,"properties":{"id":5522,"name":"Fey"},"arcs":[[-256,223,-257,-258,-259,-260,-261,-262]]},{"type":"Polygon","id":5523,"properties":{"id":5523,"name":"Froideville"},"arcs":[[-263,227,-264,-265,-266,-267]]},{"type":"Polygon","id":5527,"properties":{"id":5527,"name":"Morrens (VD)"},"arcs":[[239,-268,-269,253,219,233]]},{"type":"Polygon","id":5529,"properties":{"id":5529,"name":"Oulens-sous-Echallens"},"arcs":[[111,148,157,-270,-271,-272]]},{"type":"Polygon","id":5530,"properties":{"id":5530,"name":"Pailly"},"arcs":[[252,-273,-274,-275,261,-276]]},{"type":"Polygon","id":5531,"properties":{"id":5531,"name":"Penthéréaz"},"arcs":[[-277,-278,-279,-280,-281]]},{"type":"Polygon","id":5533,"properties":{"id":5533,"name":"Poliez-Pittet"},"arcs":[[263,232,-282,-283]]},{"type":"Polygon","id":5534,"properties":{"id":5534,"name":"Rueyres"},"arcs":[[274,-284,224,255]]},{"type":"Polygon","id":5535,"properties":{"id":5535,"name":"Saint-Barthélemy (VD)"},"arcs":[[243,215,112,271,-285]]},{"type":"Polygon","id":5537,"properties":{"id":5537,"name":"Villars-le-Terroir"},"arcs":[[-286,276,-287,259,-288,241]]},{"type":"Polygon","id":5539,"properties":{"id":5539,"name":"Vuarrens"},"arcs":[[275,260,286,280,-289,244]]},{"type":"Polygon","id":5540,"properties":{"id":5540,"name":"Montilliez"},"arcs":[[-290,281,231,242,287,258,-291]]},{"type":"Polygon","id":5541,"properties":{"id":5541,"name":"Goumoëns"},"arcs":[[284,270,-292,277,285,240]]},{"type":"Polygon","id":5551,"properties":{"id":5551,"name":"Bonvillars"},"arcs":[[-293,-294,-295,-296,-297,-298,-299,-300]]},{"type":"Polygon","id":5552,"properties":{"id":5552,"name":"Bullet"},"arcs":[[-301,-302,-303,-304,-305,-306,-307]]},{"type":"Polygon","id":5553,"properties":{"id":5553,"name":"Champagne"},"arcs":[[-308,297,-309,-310,-311]]},{"type":"Polygon","id":5554,"properties":{"id":5554,"name":"Concise"},"arcs":[[-312,-313,-314,-315,292]]},{"type":"Polygon","id":5555,"properties":{"id":5555,"name":"Corcelles-près-Concise"},"arcs":[[-316,-317,293,314]]},{"type":"MultiPolygon","id":5556,"properties":{"id":5556,"name":"Fiez"},"arcs":[[[-318,-319,302,-320]],[[-321,309,-322,-323]]]},{"type":"Polygon","id":5557,"properties":{"id":5557,"name":"Fontaines-sur-Grandson"},"arcs":[[-324,303,318,-325,-326,-327,310,320,-328,-329]]},{"type":"Polygon","id":5559,"properties":{"id":5559,"name":"Giez"},"arcs":[[-330,327,322,-331,-332,-333,-334]]},{"type":"Polygon","id":5560,"properties":{"id":5560,"name":"Grandevent"},"arcs":[[-335,304,323]]},{"type":"Polygon","id":5561,"properties":{"id":5561,"name":"Grandson"},"arcs":[[296,-336,-337,-338,-339,330,321,308]]},{"type":"Polygon","id":5562,"properties":{"id":5562,"name":"Mauborget"},"arcs":[[325,-340,-341]]},{"type":"Polygon","id":5563,"properties":{"id":5563,"name":"Mutrux"},"arcs":[[-342,-343,312]]},{"type":"Polygon","id":5564,"properties":{"id":5564,"name":"Novalles"},"arcs":[[328,329,-344,305,334]]},{"type":"Polygon","id":5565,"properties":{"id":5565,"name":"Onnens (VD)"},"arcs":[[294,316,-345]]},{"type":"Polygon","id":5566,"properties":{"id":5566,"name":"Provence"},"arcs":[[299,-346,-347,341,311]]},{"type":"Polygon","id":5568,"properties":{"id":5568,"name":"Sainte-Croix"},"arcs":[[319,301,-348,-349,-350]]},{"type":"Polygon","id":5571,"properties":{"id":5571,"name":"Tévenon"},"arcs":[[326,340,-351,345,298,307]]},{"type":"Polygon","id":5581,"properties":{"id":5581,"name":"Belmont-sur-Lausanne"},"arcs":[[-352,-353,-354,-355]]},{"type":"Polygon","id":5582,"properties":{"id":5582,"name":"Cheseaux-sur-Lausanne"},"arcs":[[254,268,-356,-357,209,120]]},{"type":"Polygon","id":5583,"properties":{"id":5583,"name":"Crissier"},"arcs":[[210,356,-358,-359,-360,-361,-362,-363,180]]},{"type":"Polygon","id":5584,"properties":{"id":5584,"name":"Epalinges"},"arcs":[[-364,-365]]},{"type":"Polygon","id":5585,"properties":{"id":5585,"name":"Jouxtens-Mézery"},"arcs":[[358,-366,-367,-368,-369]]},{"type":"MultiPolygon","id":5586,"properties":{"id":5586,"name":"Lausanne"},"arcs":[[[-370,-371,-372,-373,-374,364,-375,236,234,228,262,-376,-377,-378,-379,-380]],[[365,357,355,267,238,-381,-382]]]},{"type":"Polygon","id":5587,"properties":{"id":5587,"name":"Le Mont-sur-Lausanne"},"arcs":[[-383,380,237,374,363,373]]},{"type":"Polygon","id":5588,"properties":{"id":5588,"name":"Paudex"},"arcs":[[354,-384,-385,-386]]},{"type":"Polygon","id":5589,"properties":{"id":5589,"name":"Prilly"},"arcs":[[-387,371,-388,367]]},{"type":"Polygon","id":5590,"properties":{"id":5590,"name":"Pully"},"arcs":[[-389,351,385,-390,377]]},{"type":"Polygon","id":5591,"properties":{"id":5591,"name":"Renens (VD)"},"arcs":[[368,387,370,-391,-392,359]]},{"type":"Polygon","id":5592,"properties":{"id":5592,"name":"Romanel-sur-Lausanne"},"arcs":[[372,386,366,381,382]]},{"type":"Polygon","id":5601,"properties":{"id":5601,"name":"Chexbres"},"arcs":[[-393,-394,-395]]},{"type":"Polygon","id":5604,"properties":{"id":5604,"name":"Forel (Lavaux)"},"arcs":[[-396,-397,-398,-399,-400]]},{"type":"Polygon","id":5606,"properties":{"id":5606,"name":"Lutry"},"arcs":[[383,353,-401,-402,-403]]},{"type":"Polygon","id":5607,"properties":{"id":5607,"name":"Puidoux"},"arcs":[[399,-404,-405,-406,-407,393,-408,-409,-410]]},{"type":"Polygon","id":5609,"properties":{"id":5609,"name":"Rivaz"},"arcs":[[-411,-412,407,392]]},{"type":"Polygon","id":5610,"properties":{"id":5610,"name":"Saint-Saphorin (Lavaux)"},"arcs":[[394,406,-413,-414,410]]},{"type":"Polygon","id":5611,"properties":{"id":5611,"name":"Savigny"},"arcs":[[376,-415,-416,396,-417,400,352,388]]},{"type":"Polygon","id":5613,"properties":{"id":5613,"name":"Bourg-en-Lavaux"},"arcs":[[409,-418,401,416,395]]},{"type":"Polygon","id":5621,"properties":{"id":5621,"name":"Aclens"},"arcs":[[-419,-420,-421,-422,165,214,-423]]},{"type":"Polygon","id":5622,"properties":{"id":5622,"name":"Bremblens"},"arcs":[[-424,-425,-426,-427,-428,418]]},{"type":"Polygon","id":5623,"properties":{"id":5623,"name":"Buchillon"},"arcs":[[-429,-430,-431,-432]]},{"type":"Polygon","id":5624,"properties":{"id":5624,"name":"Bussigny"},"arcs":[[422,213,-433,361,-434,-435,423]]},{"type":"Polygon","id":5627,"properties":{"id":5627,"name":"Chavannes-près-Renens"},"arcs":[[-436,390,369]]},{"type":"Polygon","id":5628,"properties":{"id":5628,"name":"Chigny"},"arcs":[[-437,-438,-439,-440]]},{"type":"Polygon","id":5629,"properties":{"id":5629,"name":"Clarmont"},"arcs":[[-441,-442,-443]]},{"type":"Polygon","id":5631,"properties":{"id":5631,"name":"Denens"},"arcs":[[-444,-445,-446,-447,-448,-449]]},{"type":"Polygon","id":5632,"properties":{"id":5632,"name":"Denges"},"arcs":[[-450,-451,-452,-453,-454]]},{"type":"Polygon","id":5633,"properties":{"id":5633,"name":"Echandens"},"arcs":[[-455,424,434,-456,451]]},{"type":"Polygon","id":5634,"properties":{"id":5634,"name":"Echichens"},"arcs":[[442,-457,-458,420,-459,426,-460,-461,-462,-463]]},{"type":"Polygon","id":5635,"properties":{"id":5635,"name":"Ecublens (VD)"},"arcs":[[433,360,391,435,-464,452,455]]},{"type":"Polygon","id":5636,"properties":{"id":5636,"name":"Etoy"},"arcs":[[431,-465,50,-466,-467,-468]]},{"type":"Polygon","id":5637,"properties":{"id":5637,"name":"Lavigny"},"arcs":[[465,49,97,-469,-470]]},{"type":"Polygon","id":5638,"properties":{"id":5638,"name":"Lonay"},"arcs":[[450,-471,-472,459,425,454]]},{"type":"Polygon","id":5639,"properties":{"id":5639,"name":"Lully (VD)"},"arcs":[[-473,-474,-475,447,-476,436]]},{"type":"Polygon","id":5640,"properties":{"id":5640,"name":"Lussy-sur-Morges"},"arcs":[[448,474,-477,-478]]},{"type":"Polygon","id":5642,"properties":{"id":5642,"name":"Morges"},"arcs":[[-479,-480,-481,438,-482,460,471]]},{"type":"Polygon","id":5643,"properties":{"id":5643,"name":"Préverenges"},"arcs":[[-483,-484,478,470,449]]},{"type":"Polygon","id":5645,"properties":{"id":5645,"name":"Romanel-sur-Morges"},"arcs":[[427,458,419]]},{"type":"Polygon","id":5646,"properties":{"id":5646,"name":"Saint-Prex"},"arcs":[[467,-485,476,473,-486,-487,428]]},{"type":"Polygon","id":5648,"properties":{"id":5648,"name":"Saint-Sulpice (VD)"},"arcs":[[453,463,379,-488,482]]},{"type":"Polygon","id":5649,"properties":{"id":5649,"name":"Tolochenaz"},"arcs":[[439,480,-489,485,472]]},{"type":"Polygon","id":5650,"properties":{"id":5650,"name":"Vaux-sur-Morges"},"arcs":[[-490,440,462,-491]]},{"type":"Polygon","id":5651,"properties":{"id":5651,"name":"Villars-Sainte-Croix"},"arcs":[[212,181,362,432]]},{"type":"Polygon","id":5652,"properties":{"id":5652,"name":"Villars-sous-Yens"},"arcs":[[477,484,466,469,-492,443]]},{"type":"Polygon","id":5653,"properties":{"id":5653,"name":"Vufflens-le-Château"},"arcs":[[-493,490,461,481,437,475,446]]},{"type":"Polygon","id":5654,"properties":{"id":5654,"name":"Vullierens"},"arcs":[[457,-494,169,208,166,421]]},{"type":"Polygon","id":5655,"properties":{"id":5655,"name":"Yens"},"arcs":[[62,-495,444,491,468,96,70]]},{"type":"Polygon","id":5656,"properties":{"id":5656,"name":"Hautemorges"},"arcs":[[492,445,494,61,94,193,178,173,131,170,493,456,441,489]]},{"type":"Polygon","id":5661,"properties":{"id":5661,"name":"Boulens"},"arcs":[[256,222,-496]]},{"type":"Polygon","id":5663,"properties":{"id":5663,"name":"Bussy-sur-Moudon"},"arcs":[[-497,-498,-499]]},{"type":"Polygon","id":5665,"properties":{"id":5665,"name":"Chavannes-sur-Moudon"},"arcs":[[-500,-501,-502,-503]]},{"type":"Polygon","id":5669,"properties":{"id":5669,"name":"Curtilles"},"arcs":[[-504,-505,-506,-507,-508,-509]]},{"type":"Polygon","id":5671,"properties":{"id":5671,"name":"Dompierre (VD)"},"arcs":[[-510,-511,507,-512,-513]]},{"type":"Polygon","id":5673,"properties":{"id":5673,"name":"Hermenches"},"arcs":[[-514,-515,-516,-517,-518,-519,-520]]},{"type":"Polygon","id":5674,"properties":{"id":5674,"name":"Lovatens"},"arcs":[[-521,508,510,-522,-523]]},{"type":"MultiPolygon","id":5675,"properties":{"id":5675,"name":"Lucens"},"arcs":[[[-524,505,-525,497,-526,-527,-528]],[[-529,503,520,-530,499]]]},{"type":"Polygon","id":5678,"properties":{"id":5678,"name":"Moudon"},"arcs":[[502,-531,-532,-533,516,-534,-535,498,524,504,528]]},{"type":"Polygon","id":5680,"properties":{"id":5680,"name":"Ogens"},"arcs":[[-536,-537,226,-538]]},{"type":"Polygon","id":5683,"properties":{"id":5683,"name":"Prévonloup"},"arcs":[[521,509,-539]]},{"type":"Polygon","id":5684,"properties":{"id":5684,"name":"Rossenges"},"arcs":[[-540,517,532]]},{"type":"Polygon","id":5688,"properties":{"id":5688,"name":"Syens"},"arcs":[[-541,518,539,531,-542]]},{"type":"Polygon","id":5690,"properties":{"id":5690,"name":"Villars-le-Comte"},"arcs":[[-543,526,-544]]},{"type":"Polygon","id":5692,"properties":{"id":5692,"name":"Vucherens"},"arcs":[[540,-545,-546,-547,519]]},{"type":"Polygon","id":5693,"properties":{"id":5693,"name":"Montanaire"},"arcs":[[-548,-549,543,525,496,534,-550,290,257,495,221,536,-551,-552,-553,-554]]},{"type":"Polygon","id":5701,"properties":{"id":5701,"name":"Arnex-sur-Nyon"},"arcs":[[-555,-556,-557,-558]]},{"type":"Polygon","id":5702,"properties":{"id":5702,"name":"Arzier-Le Muids"},"arcs":[[-559,-560,-561,-562,-563,-564,-565]]},{"type":"Polygon","id":5703,"properties":{"id":5703,"name":"Bassins"},"arcs":[[91,-566,-567,-568,559,-569]]},{"type":"Polygon","id":5704,"properties":{"id":5704,"name":"Begnins"},"arcs":[[566,-570,-571,-572,-573,-574]]},{"type":"Polygon","id":5705,"properties":{"id":5705,"name":"Bogis-Bossey"},"arcs":[[-575,-576,-577,-578,-579,-580]]},{"type":"Polygon","id":5706,"properties":{"id":5706,"name":"Borex"},"arcs":[[-581,554,-582,-583,-584,-585]]},{"type":"Polygon","id":5707,"properties":{"id":5707,"name":"Chavannes-de-Bogis"},"arcs":[[576,-586,-587,-588,-589]]},{"type":"Polygon","id":5708,"properties":{"id":5708,"name":"Chavannes-des-Bois"},"arcs":[[-590,-591,-592,-593]]},{"type":"Polygon","id":5709,"properties":{"id":5709,"name":"Chéserex"},"arcs":[[-594,-595,-596,-597,582]]},{"type":"Polygon","id":5710,"properties":{"id":5710,"name":"Coinsins"},"arcs":[[-598,-599,-600,-601]]},{"type":"Polygon","id":5711,"properties":{"id":5711,"name":"Commugny"},"arcs":[[-602,587,-603,-604,-605,589]]},{"type":"Polygon","id":5712,"properties":{"id":5712,"name":"Coppet"},"arcs":[[-606,603,-607,-608]]},{"type":"Polygon","id":5713,"properties":{"id":5713,"name":"Crans (VD)"},"arcs":[[-609,-610,556,-611]]},{"type":"Polygon","id":5714,"properties":{"id":5714,"name":"Crassier"},"arcs":[[581,557,-612,578,-613,-614,593]]},{"type":"Polygon","id":5715,"properties":{"id":5715,"name":"Duillier"},"arcs":[[-615,-616,-617,599,-618,-619]]},{"type":"Polygon","id":5716,"properties":{"id":5716,"name":"Eysins"},"arcs":[[610,555,580,-620,-621]]},{"type":"Polygon","id":5717,"properties":{"id":5717,"name":"Founex"},"arcs":[[586,-622,574,-623,606,602]]},{"type":"Polygon","id":5718,"properties":{"id":5718,"name":"Genolier"},"arcs":[[600,616,-624,561,-625]]},{"type":"Polygon","id":5719,"properties":{"id":5719,"name":"Gingins"},"arcs":[[-626,-627,-628,-629,595,-630]]},{"type":"Polygon","id":5720,"properties":{"id":5720,"name":"Givrins"},"arcs":[[-631,562,623,615,-632]]},{"type":"Polygon","id":5721,"properties":{"id":5721,"name":"Gland"},"arcs":[[-633,-634,-635,572,-636,-637]]},{"type":"Polygon","id":5722,"properties":{"id":5722,"name":"Grens"},"arcs":[[-638,-639,583,596,628,-640]]},{"type":"Polygon","id":5723,"properties":{"id":5723,"name":"Mies"},"arcs":[[591,-641,-642]]},{"type":"Polygon","id":5724,"properties":{"id":5724,"name":"Nyon"},"arcs":[[620,-643,637,-644,618,-645,-646,608]]},{"type":"Polygon","id":5725,"properties":{"id":5725,"name":"Prangins"},"arcs":[[633,-647,644,617,598,-648]]},{"type":"Polygon","id":5726,"properties":{"id":5726,"name":"La Rippe"},"arcs":[[629,594,613,-649]]},{"type":"Polygon","id":5727,"properties":{"id":5727,"name":"Saint-Cergue"},"arcs":[[563,630,-650,626,-651]]},{"type":"Polygon","id":5728,"properties":{"id":5728,"name":"Signy-Avenex"},"arcs":[[584,638,642,619]]},{"type":"Polygon","id":5729,"properties":{"id":5729,"name":"Tannay"},"arcs":[[-652,640,590,604,605]]},{"type":"Polygon","id":5730,"properties":{"id":5730,"name":"Trélex"},"arcs":[[643,639,627,649,631,614]]},{"type":"Polygon","id":5731,"properties":{"id":5731,"name":"Le Vaud"},"arcs":[[-653,569,565,90]]},{"type":"Polygon","id":5732,"properties":{"id":5732,"name":"Vich"},"arcs":[[624,560,567,573,634,647,597]]},{"type":"Polygon","id":5741,"properties":{"id":5741,"name":"L'Abergement"},"arcs":[[-654,-655,-656,-657,-658,-659]]},{"type":"Polygon","id":5742,"properties":{"id":5742,"name":"Agiez"},"arcs":[[-660,-661,-662,-663,-664,-665]]},{"type":"Polygon","id":5743,"properties":{"id":5743,"name":"Arnex-sur-Orbe"},"arcs":[[204,206,-666,-667,664,-668,-669,-670]]},{"type":"Polygon","id":5744,"properties":{"id":5744,"name":"Ballaigues"},"arcs":[[-671,-672,-673,-674]]},{"type":"Polygon","id":5745,"properties":{"id":5745,"name":"Baulmes"},"arcs":[[-675,348,-676,-677,-678,657]]},{"type":"Polygon","id":5746,"properties":{"id":5746,"name":"Bavois"},"arcs":[[669,-679,278,291,269,156,197,202]]},{"type":"Polygon","id":5747,"properties":{"id":5747,"name":"Bofflens"},"arcs":[[666,-680,-681,-682,659]]},{"type":"Polygon","id":5748,"properties":{"id":5748,"name":"Bretonnières"},"arcs":[[-683,-684,660,681,-685]]},{"type":"Polygon","id":5749,"properties":{"id":5749,"name":"Chavornay"},"arcs":[[668,-686,-687,-688,245,288,279,678]]},{"type":"Polygon","id":5750,"properties":{"id":5750,"name":"Les Clées"},"arcs":[[-689,-690,661,683,-691,-692,671,-693,654]]},{"type":"MultiPolygon","id":5752,"properties":{"id":5752,"name":"Croy"},"arcs":[[[-694,679,665,205]],[[-695,160,188]]]},{"type":"Polygon","id":5754,"properties":{"id":5754,"name":"Juriens"},"arcs":[[-696,190,-697,-698,186]]},{"type":"Polygon","id":5755,"properties":{"id":5755,"name":"Lignerolle"},"arcs":[[-699,655,692,670]]},{"type":"Polygon","id":5756,"properties":{"id":5756,"name":"Montcherand"},"arcs":[[662,689,-700,-701,-702]]},{"type":"Polygon","id":5757,"properties":{"id":5757,"name":"Orbe"},"arcs":[[701,-703,-704,-705,685,667,663]]},{"type":"Polygon","id":5758,"properties":{"id":5758,"name":"La Praz"},"arcs":[[185,191,695]]},{"type":"Polygon","id":5759,"properties":{"id":5759,"name":"Premier"},"arcs":[[-706,690,682,-707,-708]]},{"type":"Polygon","id":5760,"properties":{"id":5760,"name":"Rances"},"arcs":[[658,677,-709,-710,-711,-712]]},{"type":"Polygon","id":5761,"properties":{"id":5761,"name":"Romainmôtier-Envy"},"arcs":[[207,161,694,187,697,-713,706,684,680,693]]},{"type":"Polygon","id":5762,"properties":{"id":5762,"name":"Sergey"},"arcs":[[711,-714,699,688,653]]},{"type":"Polygon","id":5763,"properties":{"id":5763,"name":"Valeyres-sous-Rances"},"arcs":[[-715,702,700,713,710]]},{"type":"Polygon","id":5764,"properties":{"id":5764,"name":"Vallorbe"},"arcs":[[-716,-717,-718,-719,672,691,705]]},{"type":"Polygon","id":5765,"properties":{"id":5765,"name":"Vaulion"},"arcs":[[-720,715,707,712,696,189]]},{"type":"Polygon","id":5766,"properties":{"id":5766,"name":"Vuiteboeuf"},"arcs":[[-721,-722,-723,675,347,300]]},{"type":"Polygon","id":5785,"properties":{"id":5785,"name":"Corcelles-le-Jorat"},"arcs":[[-724,-725,-726,265,-727,514,-728]]},{"type":"Polygon","id":5790,"properties":{"id":5790,"name":"Maracon"},"arcs":[[-729,-730]]},{"type":"Polygon","id":5792,"properties":{"id":5792,"name":"Montpreveyres"},"arcs":[[266,725,-731,723,-732,-733,-734,414,375]]},{"type":"MultiPolygon","id":5798,"properties":{"id":5798,"name":"Ropraz"},"arcs":[[[731,727,513,546,-735]],[[730,724]]]},{"type":"Polygon","id":5799,"properties":{"id":5799,"name":"Servion"},"arcs":[[397,415,733,-736,-737,-738]]},{"type":"Polygon","id":5803,"properties":{"id":5803,"name":"Vulliens"},"arcs":[[541,530,501,-739,-740,544]]},{"type":"Polygon","id":5804,"properties":{"id":5804,"name":"Jorat-Menthue"},"arcs":[[549,533,515,726,264,282,289]]},{"type":"Polygon","id":5805,"properties":{"id":5805,"name":"Oron"},"arcs":[[403,398,737,-741,729,-742]]},{"type":"Polygon","id":5806,"properties":{"id":5806,"name":"Jorat-Mézières"},"arcs":[[734,545,739,-743,735,732]]},{"type":"Polygon","id":5812,"properties":{"id":5812,"name":"Champtauroz"},"arcs":[[-744,-745,-746,-747,-748,-749]]},{"type":"Polygon","id":5813,"properties":{"id":5813,"name":"Chevroux"},"arcs":[[-750,-751]]},{"type":"Polygon","id":5816,"properties":{"id":5816,"name":"Corcelles-près-Payerne"},"arcs":[[-752,-753,-754,-755,-756]]},{"type":"Polygon","id":5817,"properties":{"id":5817,"name":"Grandcour"},"arcs":[[-757,749,-758,753,-759]]},{"type":"Polygon","id":5819,"properties":{"id":5819,"name":"Henniez"},"arcs":[[-760,-761,-762,-763]]},{"type":"Polygon","id":5821,"properties":{"id":5821,"name":"Missy"},"arcs":[[755,-764]]},{"type":"Polygon","id":5822,"properties":{"id":5822,"name":"Payerne"},"arcs":[[758,752,-765,-766,-767]]},{"type":"Polygon","id":5827,"properties":{"id":5827,"name":"Trey"},"arcs":[[-768,-769,765,-770]]},{"type":"Polygon","id":5828,"properties":{"id":5828,"name":"Treytorrens (Payerne)"},"arcs":[[-771,746,-772,-773]]},{"type":"Polygon","id":5830,"properties":{"id":5830,"name":"Villarzel"},"arcs":[[760,-774,-775,-776]]},{"type":"MultiPolygon","id":5831,"properties":{"id":5831,"name":"Valbroye"},"arcs":[[[-777,747,770,-778,767,-779,773,759,-780,547]],[[775,-781,511,506,523,-782,761]]]},{"type":"Polygon","id":5841,"properties":{"id":5841,"name":"Château-d'Oex"},"arcs":[[-783,-784,-785,38,36,46,-786]]},{"type":"Polygon","id":5842,"properties":{"id":5842,"name":"Rossinière"},"arcs":[[785,45,-787,-788]]},{"type":"Polygon","id":5843,"properties":{"id":5843,"name":"Rougemont"},"arcs":[[-789,783]]},{"type":"Polygon","id":5851,"properties":{"id":5851,"name":"Allaman"},"arcs":[[-790,77,51,464,430,-791]]},{"type":"Polygon","id":5852,"properties":{"id":5852,"name":"Bursinel"},"arcs":[[-792,-793,-794,-795,-796]]},{"type":"Polygon","id":5853,"properties":{"id":5853,"name":"Bursins"},"arcs":[[-797,-798,-799,795,-800,-801]]},{"type":"Polygon","id":5854,"properties":{"id":5854,"name":"Burtigny"},"arcs":[[88,99,-802,-803,797,-804,-805,570,652,89]]},{"type":"Polygon","id":5855,"properties":{"id":5855,"name":"Dully"},"arcs":[[636,-806,799,794,-807]]},{"type":"Polygon","id":5856,"properties":{"id":5856,"name":"Essertines-sur-Rolle"},"arcs":[[-808,-809,801,98,83,54,75,-810]]},{"type":"Polygon","id":5857,"properties":{"id":5857,"name":"Gilly"},"arcs":[[798,802,808,-811,-812,791]]},{"type":"Polygon","id":5858,"properties":{"id":5858,"name":"Luins"},"arcs":[[800,805,635,571,804,-813]]},{"type":"Polygon","id":5859,"properties":{"id":5859,"name":"Mont-sur-Rolle"},"arcs":[[809,74,-814,-815,-816]]},{"type":"Polygon","id":5860,"properties":{"id":5860,"name":"Perroy"},"arcs":[[-817,-818,813,73,76,789]]},{"type":"Polygon","id":5861,"properties":{"id":5861,"name":"Rolle"},"arcs":[[792,811,-819,814,817,-820]]},{"type":"Polygon","id":5862,"properties":{"id":5862,"name":"Tartegnin"},"arcs":[[815,818,810,807]]},{"type":"Polygon","id":5863,"properties":{"id":5863,"name":"Vinzel"},"arcs":[[812,803,796]]},{"type":"Polygon","id":5871,"properties":{"id":5871,"name":"L'Abbaye"},"arcs":[[192,171,195,-821,-822,716,719]]},{"type":"Polygon","id":5872,"properties":{"id":5872,"name":"Le Chenit"},"arcs":[[-823,-824,820,194,64,69,81,95,85,92,568,558]]},{"type":"Polygon","id":5873,"properties":{"id":5873,"name":"Le Lieu"},"arcs":[[717,821,823,-825]]},{"type":"Polygon","id":5882,"properties":{"id":5882,"name":"Chardonne"},"arcs":[[-826,412,405,-827,-828,-829,-830]]},{"type":"Polygon","id":5883,"properties":{"id":5883,"name":"Corseaux"},"arcs":[[-831,-832,829,-833]]},{"type":"Polygon","id":5884,"properties":{"id":5884,"name":"Corsier-sur-Vevey"},"arcs":[[-834,-835,832,828,-836,-837]]},{"type":"Polygon","id":5885,"properties":{"id":5885,"name":"Jongny"},"arcs":[[827,-838,835]]},{"type":"Polygon","id":5886,"properties":{"id":5886,"name":"Montreux"},"arcs":[[-839,27,-840,-841,-842]]},{"type":"Polygon","id":5889,"properties":{"id":5889,"name":"La Tour-de-Peilz"},"arcs":[[26,-843,-844,839]]},{"type":"Polygon","id":5890,"properties":{"id":5890,"name":"Vevey"},"arcs":[[-845,842,25,-846,830,834]]},{"type":"Polygon","id":5891,"properties":{"id":5891,"name":"Veytaux"},"arcs":[[-847,786,44,838]]},{"type":"Polygon","id":5892,"properties":{"id":5892,"name":"Blonay - Saint-Légier"},"arcs":[[840,843,844,833,-848]]},{"type":"Polygon","id":5902,"properties":{"id":5902,"name":"Belmont-sur-Yverdon"},"arcs":[[-849,-850,-851,247]]},{"type":"Polygon","id":5903,"properties":{"id":5903,"name":"Bioley-Magnoux"},"arcs":[[-852,550,535,-853,-854]]},{"type":"Polygon","id":5904,"properties":{"id":5904,"name":"Chamblon"},"arcs":[[-855,-856,-857,-858]]},{"type":"Polygon","id":5905,"properties":{"id":5905,"name":"Champvent"},"arcs":[[-859,708,676,722,-860,-861,-862,856,-863]]},{"type":"Polygon","id":5907,"properties":{"id":5907,"name":"Chavannes-le-Chêne"},"arcs":[[-864,-865,771,745,-866,-867]]},{"type":"Polygon","id":5908,"properties":{"id":5908,"name":"Chêne-Pâquier"},"arcs":[[865,744,-868,-869]]},{"type":"Polygon","id":5909,"properties":{"id":5909,"name":"Cheseaux-Noréaz"},"arcs":[[-870,335,295,344,-871,-872,-873]]},{"type":"Polygon","id":5910,"properties":{"id":5910,"name":"Cronay"},"arcs":[[-874,-875,-876,-877,-878,-879]]},{"type":"Polygon","id":5911,"properties":{"id":5911,"name":"Cuarny"},"arcs":[[872,-880,-881,876,-882,-883]]},{"type":"Polygon","id":5912,"properties":{"id":5912,"name":"Démoret"},"arcs":[[-884,552,-885,-886,867,743]]},{"type":"Polygon","id":5913,"properties":{"id":5913,"name":"Donneloye"},"arcs":[[-887,878,-888,-889,884,551,851]]},{"type":"Polygon","id":5914,"properties":{"id":5914,"name":"Ependes (VD)"},"arcs":[[-890,-891,-892,-893,849,-894,686,704]]},{"type":"Polygon","id":5919,"properties":{"id":5919,"name":"Mathod"},"arcs":[[-895,889,703,714,709,858]]},{"type":"Polygon","id":5921,"properties":{"id":5921,"name":"Molondin"},"arcs":[[866,868,885,888,-896,-897]]},{"type":"Polygon","id":5922,"properties":{"id":5922,"name":"Montagny-près-Yverdon"},"arcs":[[857,861,-898,337,-899,-900]]},{"type":"Polygon","id":5923,"properties":{"id":5923,"name":"Oppens"},"arcs":[[-901,852,537,225,283,273]]},{"type":"Polygon","id":5924,"properties":{"id":5924,"name":"Orges"},"arcs":[[332,-902,859,721,-903]]},{"type":"Polygon","id":5925,"properties":{"id":5925,"name":"Orzens"},"arcs":[[853,900,272,251,-904,873,886]]},{"type":"Polygon","id":5926,"properties":{"id":5926,"name":"Pomy"},"arcs":[[875,-905,-906,-907,881]]},{"type":"Polygon","id":5928,"properties":{"id":5928,"name":"Rovray"},"arcs":[[896,-908,-909,863]]},{"type":"Polygon","id":5929,"properties":{"id":5929,"name":"Suchy"},"arcs":[[687,893,848,246]]},{"type":"Polygon","id":5930,"properties":{"id":5930,"name":"Suscévaz"},"arcs":[[890,894,862,855,-910]]},{"type":"Polygon","id":5931,"properties":{"id":5931,"name":"Treycovagnes"},"arcs":[[899,-911,891,909,854]]},{"type":"Polygon","id":5932,"properties":{"id":5932,"name":"Ursins"},"arcs":[[874,903,250,-912,904]]},{"type":"Polygon","id":5933,"properties":{"id":5933,"name":"Valeyres-sous-Montagny"},"arcs":[[897,860,901,331,338]]},{"type":"Polygon","id":5934,"properties":{"id":5934,"name":"Valeyres-sous-Ursins"},"arcs":[[905,911,249,-913]]},{"type":"Polygon","id":5935,"properties":{"id":5935,"name":"Villars-Epeney"},"arcs":[[871,-914,879]]},{"type":"Polygon","id":5937,"properties":{"id":5937,"name":"Vugelles-La Mothe"},"arcs":[[306,343,333,902,720]]},{"type":"Polygon","id":5938,"properties":{"id":5938,"name":"Yverdon-les-Bains"},"arcs":[[869,882,906,912,248,850,892,910,898,336]]},{"type":"Polygon","id":5939,"properties":{"id":5939,"name":"Yvonand"},"arcs":[[887,877,880,913,870,315,-915,907,895]]}]}},"arcs":[[[77051,17837],[-687,-386],[-207,-10],[-247,-235],[-135,-14],[-272,185],[-953,-183],[-615,-36],[-478,49],[-318,160]],[[81508,19327],[-160,-297],[-1065,-1062],[-710,-463],[-2116,-764],[-412,203],[-90,333],[155,469],[-59,91]],[[81859,18794],[-351,533]],[[74594,13071],[515,549],[179,126],[844,240],[-4,153],[483,143],[-28,263],[794,596],[451,223],[487,39],[328,96],[672,379],[27,186],[210,172],[332,171],[562,354],[156,18],[193,391],[284,238],[120,217],[309,373],[162,115],[238,5],[346,-201],[-86,247],[-425,501],[116,129]],[[73139,17367],[36,-440],[-46,-752],[104,-402],[77,-529],[125,-456],[34,-674],[193,-419],[373,-310],[559,-314]],[[79505,4134],[1020,623],[676,257],[375,110],[1065,-245],[201,-188],[210,-79],[529,123],[223,-491],[-27,-315],[282,-500],[680,-433],[133,-324],[-96,-553],[-115,-141],[176,-252]],[[76345,9640],[444,-550],[393,-382],[443,-342],[211,-378],[102,-826],[401,-544],[237,-507],[214,-118],[238,-323],[33,-375],[-35,-382],[63,-299],[290,-250],[126,-230]],[[83855,11974],[-494,167],[-42,153],[-553,79],[-228,96],[-247,-128],[-391,-374],[-118,-20],[-182,-218],[-308,32],[-37,-176],[-298,-245],[-120,-239],[-560,-458],[-792,-379],[-181,-35],[-1208,-87],[-397,-93],[-192,51],[-1162,-460]],[[91669,14411],[-209,19],[-1060,-424],[-286,-293],[-98,17],[-224,-192],[-558,-201],[-117,-184],[-9,-1102],[-483,-143],[-83,-135],[-459,-141],[-407,10],[-243,126],[-380,-199],[-472,-182],[-258,-47],[-469,-204],[-126,8],[-257,-252],[-196,-336],[60,-240],[-194,-201],[-331,-9],[-397,-220],[-244,40],[-463,-48],[-79,564],[-318,-27],[-16,239],[168,326],[3,268],[151,246],[219,84],[21,396]],[[94853,14547],[-2784,95],[-400,-231]],[[84837,1726],[438,-251],[448,92],[360,201],[210,23],[504,485],[198,275],[246,25],[175,213],[393,175],[433,389],[146,263],[220,178],[-63,86],[232,209],[195,343],[194,68],[-77,194],[43,182],[-49,370],[188,397],[65,428],[168,155],[760,-80],[493,166],[367,462],[415,189],[106,198],[31,419],[295,584],[455,56],[391,390],[340,490],[196,102],[39,193],[314,388],[211,353],[470,-16],[399,273],[79,339],[-165,627],[-88,557],[337,269],[229,-16],[157,99],[-81,338],[260,93],[-648,757],[-13,1091]],[[70102,19262],[1236,866]],[[69362,22360],[-124,-458],[-262,-542],[-41,-377],[90,-207],[365,-321],[259,-395],[259,-535],[194,-263]],[[70711,21888],[-33,-149],[-201,132],[-371,-145],[-78,441],[-194,-41],[-54,196],[-418,38]],[[71338,20128],[-487,285],[341,140],[-67,183],[233,86],[-58,187],[-589,879]],[[74395,21697],[172,-134],[454,-72],[-45,-143],[159,-478],[-364,-169],[-195,-304],[132,-651],[252,-595],[135,-414],[187,3],[101,-115],[304,270],[274,-96],[385,588],[1557,1009],[-46,-495]],[[73750,22965],[211,45],[267,-189],[-88,-296],[215,-145],[3,-174],[383,108],[123,-140],[-469,-477]],[[79977,27261],[-172,5],[-393,-139],[-383,-297],[-213,-437],[-169,-125],[-147,178],[-398,-598],[-520,-450],[-242,-283],[-424,-171],[-425,-76],[-89,-164],[-249,-51],[-122,94],[-482,-305],[-245,-258],[-337,-475],[-312,-201],[-117,-150],[-196,21],[-40,-136],[-269,-176],[-283,-102]],[[80135,24704],[148,329],[-5,406],[-241,163],[-113,-72],[59,299],[221,329],[36,274],[-193,245],[-70,584]],[[77857,19901],[83,19],[397,517],[348,30],[212,482],[-41,870],[84,123],[-239,423],[-95,427],[13,178],[142,198],[256,-16],[694,417],[234,319],[68,543],[122,273]],[[91268,14656],[-296,136],[-358,242],[-269,-5],[-921,255],[-269,-111],[-284,189],[-501,-4],[-457,-201],[-249,-7],[-762,-301],[-267,-262],[-257,-377],[-90,48],[-156,-232],[-391,-284],[-100,-293],[-221,-240],[-422,-293],[-126,-531],[-617,-382],[-400,-29]],[[91669,14411],[-125,133],[-276,112]],[[79505,4134],[120,-593],[205,-1256],[701,-471],[448,-578],[132,-362],[175,-312],[146,-128],[173,-434],[70,109],[294,8],[491,232],[536,344],[196,36],[66,140],[304,200],[234,35],[147,207],[277,222],[617,193]],[[81508,19327],[-44,256],[-155,120],[250,219],[-119,105],[36,460],[-34,308],[183,134],[-94,105],[28,287],[167,148],[372,887],[24,372],[189,820],[-88,84],[118,181],[-354,298],[-320,440],[-774,219],[-371,-65],[-387,-1]],[[77857,19901],[-182,-866],[-488,-758],[-156,-303],[20,-137]],[[64802,29719],[-881,389]],[[67087,28707],[-2285,1012]],[[68799,27949],[-1712,758]],[[72812,24897],[-262,459],[-84,394],[-279,333],[-89,233],[-430,361],[-2869,1272]],[[71058,22275],[143,965],[-96,469],[614,331],[-71,224],[570,464],[594,169]],[[70711,21888],[98,370],[249,17]],[[63921,30108],[267,-296],[2759,-3636],[341,-544],[655,-666],[307,-431],[187,-179],[391,-234],[400,-475],[91,-412],[43,-875]],[[74594,13071],[763,-765],[193,-333],[232,-1160],[51,-369],[185,-384],[327,-420]],[[89221,18714],[-134,-146],[78,-297],[-250,-683],[-433,-82],[-192,-123],[-226,86],[-406,-124],[-295,-246],[-360,-81],[-10,391],[59,277],[-391,133],[-249,335],[-625,-240],[-358,-9],[-97,289],[-333,183],[-484,-100],[-877,472],[-172,20],[-615,237],[-283,-79],[-393,-4],[-107,94],[-209,-223]],[[91268,14656],[53,295],[-85,176],[249,7],[-101,420],[7,242],[-386,141],[208,577],[13,281],[-126,449],[-146,149],[-586,139],[-266,311],[-365,317],[-516,554]],[[82382,29543],[-121,6],[-325,-374],[-406,-329],[-754,-771],[-432,-290],[-293,-338],[-74,-186]],[[90555,24150],[-114,692],[-315,873],[-201,240],[-471,1351],[-466,286],[-105,386],[-270,42],[-425,176],[-353,210],[-761,261],[-812,-603],[-510,-783],[-278,-153],[-151,688],[57,244],[-42,564],[-156,588],[-160,393],[-436,273],[-1915,-58],[-289,-277]],[[89221,18714],[-601,194],[-607,-258],[-192,75],[-213,240],[103,587],[-159,679],[-480,25],[-390,207],[-2,316],[108,372],[156,-45],[482,1],[-118,399],[-271,248],[-54,253],[67,274],[324,289],[51,320],[-378,202],[438,163],[179,4],[776,460],[607,155],[980,-144],[528,420]],[[95275,23947],[-182,-234],[-489,-230],[-338,390],[-278,171],[-295,-35],[-331,137],[-323,-27],[-251,150],[-1004,163],[-190,-85],[-269,-2],[-323,-248],[-447,53]],[[94853,14547],[2749,3160],[109,2416],[-322,1122],[641,208],[127,243],[180,97],[-168,54],[-204,277],[-506,-313],[-284,-36],[-449,729],[-57,431],[-74,186],[-181,121],[35,491],[59,157],[-226,118],[-186,-113],[-821,52]],[[72603,23104],[268,1130],[18,528],[-77,135]],[[71058,22275],[752,661],[137,-247],[371,161],[204,-80],[81,334]],[[73750,22965],[-240,-90],[-237,31],[-477,197],[-193,1]],[[71338,20128],[340,-60],[388,62],[1062,237],[226,19],[-96,347],[561,254],[576,710]],[[80873,32030],[-979,-633],[-633,-65],[-562,-131],[-424,-290],[-318,-14],[-608,-364],[-410,87],[-203,-161],[-299,-446],[-262,-136],[-293,-251],[-838,-591],[-470,-500],[-389,-197],[-187,-280],[-335,-336],[-280,-89],[-266,72],[-4318,244]],[[81052,31663],[-179,367]],[[82382,29543],[-13,152],[-598,-182],[-693,-86],[-179,46],[-567,-27],[-27,898],[-73,413],[216,408],[279,339],[325,159]],[[70102,19262],[426,-241],[318,-16],[870,123],[178,-7],[357,-221],[678,-895],[124,-236],[86,-402]],[[28123,39253],[-235,125],[-90,160],[-296,53],[-150,-54],[-433,414],[-294,422],[-285,67],[27,223],[-221,299],[-140,-51],[-157,287],[-143,23],[-424,658],[-234,144]],[[28965,37542],[-87,258],[44,157],[-158,199],[134,167],[-277,635],[-200,21],[-24,150],[-249,33],[-25,91]],[[29001,37160],[-243,282],[207,100]],[[27371,36462],[807,145],[427,147],[114,239],[282,167]],[[25197,38319],[287,324],[274,-176],[329,-485],[-35,-103],[331,-252],[197,-231],[282,-39],[118,-306],[147,53],[244,-642]],[[22847,38705],[108,215],[275,140],[224,-148],[140,-239],[-163,-224],[139,-59],[391,-443],[161,-257],[593,143],[101,185],[381,301]],[[22642,39587],[116,-218],[-74,-103],[-326,-129],[231,-319],[258,-113]],[[23190,40212],[128,-89],[-676,-536]],[[24356,41822],[-352,-225],[-156,-350],[-313,-278],[-306,-31],[-142,-357],[103,-369]],[[25048,42023],[-203,50],[-303,-49],[-39,-254],[-147,52]],[[24705,45829],[-86,-221],[304,-181],[77,-125],[322,-204],[361,-385],[612,-350]],[[24972,47500],[-188,-208],[233,-207],[-184,-202],[-85,-216],[293,-189],[-160,-176],[162,-99],[-338,-374]],[[27665,48738],[-194,-228],[-198,-26],[-161,-275],[-349,81],[-94,-290],[-537,-393],[-276,-332],[-501,396],[-222,-276],[-161,105]],[[28593,44594],[177,1123],[70,65],[-224,277],[-744,368],[-123,-9],[55,527],[117,481],[149,421],[45,354],[-126,373],[-324,164]],[[26295,44363],[367,178],[292,484],[429,468],[418,-355],[75,-384],[231,90],[7,-194],[479,-56]],[[19618,49870],[-144,-215],[694,-350],[982,-169],[203,16],[-414,-605],[1480,-1810],[246,-135],[31,-170],[981,-701],[366,451],[267,-242],[99,99],[296,-210]],[[20100,50412],[-173,-132],[-309,-410]],[[20730,50619],[-630,-207]],[[24972,47500],[-97,51],[-844,746],[-28,197],[-722,903],[-420,204],[-182,139],[-375,115],[-68,-92],[-142,176],[-596,424],[-768,256]],[[21274,43970],[197,-348],[6,-144],[177,-201],[287,-189],[148,-249],[286,-325],[254,-194],[632,-309],[221,62],[327,-60],[207,32],[135,-213],[205,-10]],[[17186,47284],[221,-239],[215,-118],[410,-500],[-58,-111],[735,-44],[171,-86],[332,-788],[276,-127],[341,-358],[42,-254],[205,-172],[84,-333],[866,-17],[248,-167]],[[19618,49870],[-380,34],[-718,-683],[-407,-349],[-531,-1527],[-396,-61]],[[26043,44241],[252,122]],[[25048,42023],[-23,323],[261,398],[-105,222],[101,269],[-150,147],[133,149],[405,258],[-136,120],[152,160],[357,172]],[[25327,36878],[-16,295],[-180,273],[208,734],[-142,139]],[[23979,37213],[181,-300],[98,-392],[195,-82],[303,335],[150,84],[89,-158],[314,94],[18,84]],[[23056,38513],[211,-393],[197,-77],[347,-389],[168,-441]],[[22847,38705],[268,-116],[-59,-76]],[[25327,36878],[67,-181],[323,138],[36,-318],[253,-396],[-8,-368],[198,-149],[147,46],[238,-185]],[[26581,35465],[102,387],[227,227],[212,92],[-73,242],[322,49]],[[19073,39257],[279,391],[-5,386],[151,146],[281,33],[81,-172],[145,-43],[454,66],[575,-49],[128,-89],[142,-332],[159,12]],[[17944,40724],[250,-218],[413,-266],[-288,-335],[413,-374],[317,-118],[24,-156]],[[14973,45336],[292,-19],[152,67],[237,-52],[242,-219],[463,-249],[126,-244],[251,-132],[359,35],[198,-54],[206,-279],[22,-200],[499,-98],[233,-238],[21,-252],[354,-234],[-291,-447],[-234,-491],[730,-312],[-38,-478],[103,-84],[-131,-163],[-472,-236],[-177,-230],[-174,-3]],[[17186,47284],[-220,-176],[-349,-91],[-211,-149],[-368,-403],[-260,-393],[-359,-203],[-446,-533]],[[23190,40212],[-847,693],[-323,375],[-83,5],[-368,333],[-211,341],[54,37],[-266,550],[-366,587],[-44,183],[538,654]],[[21463,39606],[1003,-186],[176,167]],[[13515,42776],[-186,-347],[149,-306],[336,-864],[150,-151],[337,-500],[151,-515],[434,-396],[198,-17],[816,-350],[212,-226],[252,-920],[95,14],[95,-394],[584,-9],[140,-51],[-80,-302]],[[14005,43614],[-490,-838]],[[17944,40724],[-52,-85],[-442,-293],[-262,-266],[-302,-458],[-154,178],[-707,314],[-121,88],[-105,317],[-257,348],[-91,366],[-214,330],[-39,383],[68,80],[-118,278],[-84,418],[-161,336],[68,280],[-605,226],[-361,50]],[[18105,38396],[231,-45],[303,200],[32,159],[207,226],[195,321]],[[17198,37442],[187,-102],[377,239],[99,542],[244,275]],[[15743,36964],[247,102],[144,-31],[262,244],[237,70],[242,171],[323,-78]],[[11954,39728],[492,-850],[259,-625],[251,-439],[247,-45],[652,-232],[274,-136],[474,233],[395,-6],[248,-200],[188,15],[255,-122],[54,-357]],[[12565,42799],[-243,-463],[-41,-363],[-641,-712],[-248,-359],[357,-782],[-92,-174],[297,-218]],[[13515,42776],[-851,324],[-99,-301]],[[27580,49631],[-403,281],[-57,120],[-254,-12],[47,125],[-292,160],[-118,222],[-459,222],[-425,139],[-609,146],[-702,-24],[-681,-118],[-786,12],[-270,45],[-682,-6],[-511,42],[-648,-366]],[[27665,48738],[-143,164],[69,446],[-11,283]],[[14973,45336],[-368,-625],[-127,-392],[-473,-705]],[[28788,41221],[94,83],[-510,566],[-317,823],[-444,141],[-186,149],[-118,355],[-441,143],[-104,556],[-178,133],[-541,71]],[[28123,39253],[112,16],[-99,343],[236,182],[-261,208],[-81,235],[27,232],[-136,211],[594,346],[-82,105],[355,90]],[[18365,37818],[273,127],[199,232],[260,127],[149,-110],[341,304],[31,123],[202,-65],[426,-369],[298,161],[233,204],[306,167],[-360,261],[67,173],[291,13],[233,167],[149,273]],[[18105,38396],[260,-578]],[[85329,92193],[-2644,-1813],[-432,-410],[-369,-495],[-80,90],[-346,-383],[-50,64],[-445,-512],[-116,151],[-83,-471],[-294,177],[-401,-830]],[[85497,88514],[-340,143],[-167,-201],[-315,-93],[-304,65],[-210,283],[-97,491],[-218,414],[-30,195],[1513,2382]],[[80069,87761],[-307,-410],[-92,-18],[-409,-463],[-46,49],[-466,-410],[460,-582],[666,-170],[93,19],[112,267],[152,-15],[23,141],[196,149],[93,-88],[79,495],[124,-84],[299,-430],[327,137],[29,-145],[434,-162],[121,61],[299,-359],[-197,-251],[-300,-599],[564,-575],[250,-125],[-207,-287],[-200,-21],[-125,-133],[63,-218],[-369,-328],[-50,-226],[229,-384],[110,116],[185,-280],[169,-122],[181,345],[277,-178],[210,263],[311,732],[332,86],[192,300],[102,300],[318,497],[128,108],[68,237],[323,137],[-20,126],[269,215],[132,295],[-148,388],[-166,124],[-44,290],[53,148],[-471,-163],[27,519],[238,250],[-44,166],[353,103],[-11,-98],[312,194],[-97,130],[422,244],[327,298],[-60,77],[-353,-99],[-42,170]],[[75888,97560],[2107,-3318],[368,-529],[328,-396],[91,83],[183,-174],[-54,-117],[274,-81],[119,-157],[527,291],[246,321],[66,-274],[153,70],[443,-319],[-79,-68],[194,-154],[494,409],[70,-122],[291,172],[-214,353],[-210,61],[-18,120],[2238,1222],[-50,81],[573,387],[261,126]],[[84289,95547],[-73,297],[-171,178],[253,64],[-182,470],[144,69],[-131,254],[175,116],[-143,292],[284,168],[-88,247],[236,295],[-287,313],[-268,150],[-425,326],[-4069,1213],[-3656,-2439]],[[85497,88514],[395,108],[466,12],[202,101],[-22,233],[170,94],[-217,276],[388,236],[214,245],[-108,218],[-101,-39],[-219,215],[-273,430],[-1063,1550]],[[85329,92193],[-1186,1743],[287,457],[9,215],[-76,709],[-74,230]],[[75888,97560],[-2566,-1712],[2781,-3257],[263,-389],[362,-148],[190,-255],[224,-10],[327,283],[642,-393],[138,-265],[-482,-571],[225,-202],[-278,-318],[325,-320],[153,-287],[510,-555],[1367,-1400]],[[43869,53509],[225,-121],[68,250],[286,349]],[[42053,54127],[250,154],[254,-27],[283,155],[361,-84],[36,-489],[308,-53],[324,-274]],[[42688,56015],[-202,-87],[-91,-320],[-307,-546],[-38,-269],[-115,-105],[231,2],[-113,-563]],[[44088,55825],[-241,165],[28,215],[-328,128],[-172,-103],[-218,131],[-97,-214],[-142,78],[-230,-210]],[[44629,55219],[-549,281],[8,325]],[[44448,53987],[-116,47],[149,666],[148,519]],[[41148,53269],[159,-184],[-178,-338],[463,-192],[-34,-252],[-245,-198],[216,-122],[-33,-172]],[[42053,54127],[-129,-82],[-107,-321],[-201,-64],[-173,191],[-118,-50],[-177,-532]],[[43318,52427],[135,-18],[191,432],[4,226],[221,442]],[[41496,51811],[672,-118],[42,140],[180,-18],[181,234],[435,-95],[148,501],[164,-28]],[[45106,53280],[-10,132],[-355,299],[-22,195],[-271,81]],[[44986,51481],[134,324],[61,596],[-117,-13],[-117,242],[159,650]],[[44194,50965],[142,-40],[19,155],[211,-45],[36,216],[146,-62],[81,211],[157,81]],[[43318,52427],[-100,-737],[362,-43],[-40,-419],[302,-133],[-8,-159],[360,29]],[[35740,53071],[166,548],[-319,205],[138,465],[-185,103],[436,991]],[[34110,53089],[743,-120],[127,350],[300,-244],[296,81],[164,-85]],[[33791,52977],[186,164],[133,-52]],[[33293,54409],[445,-147],[-122,-381],[-2,-195],[-125,76],[-53,-192],[114,-447],[59,83],[182,-229]],[[32803,56826],[-155,-330],[441,-270],[266,-114],[-22,-307],[-148,-225],[-264,-806],[372,-365]],[[33251,57144],[-448,-318]],[[35463,56406],[-142,45],[-175,-191],[-49,-430],[-330,227],[24,142],[-316,304],[-161,-180],[-570,348],[-172,-43],[-190,-205],[-131,721]],[[35976,55383],[-247,158],[-32,380],[-233,372],[-1,113]],[[32200,51964],[224,-147],[147,166],[141,415],[233,-142],[31,156],[225,153],[-10,124],[201,225],[116,-53],[283,116]],[[31243,53147],[21,-134],[231,-205],[375,-222],[277,-413],[53,-209]],[[31719,53928],[-78,-241],[208,-70],[70,-181],[-297,-147],[-148,-178],[-231,36]],[[33293,54409],[-488,-595],[-107,178],[-551,-14],[-47,-164],[-381,114]],[[34943,58153],[-297,-153],[-288,-56],[-446,-380],[-394,-183],[-267,-237]],[[36607,58974],[-249,-50],[-290,129],[-158,-133],[-312,-98],[-247,-243],[-240,-340],[-168,-86]],[[35885,57429],[104,329],[122,-21],[73,209],[335,169],[148,237],[-96,274],[36,348]],[[35463,56406],[64,262],[257,427],[101,334]],[[37088,51256],[261,-21],[79,109],[597,-189],[-16,162],[232,47],[277,275],[371,31],[64,162]],[[35740,53071],[80,49],[402,-191],[159,306],[203,-71],[-85,-210],[341,-110],[-96,-113],[-104,-587],[268,-153],[-157,-263],[23,-188],[314,-284]],[[38095,55925],[-508,97],[-129,-309],[-303,103],[-195,-735],[-561,242],[-395,130],[-28,-70]],[[38727,54534],[-605,338],[203,279],[-77,45],[153,271],[-221,37],[48,370],[-133,51]],[[38953,51832],[-35,220],[-194,449],[139,52],[-356,399],[205,197],[-125,99],[-213,539],[201,514],[152,233]],[[32803,56826],[-487,-17],[60,237],[-161,119],[76,114],[-125,109],[130,200],[-635,434],[-13,-50],[-430,365]],[[29777,56520],[-85,-267],[918,-411],[65,35],[182,-230],[177,-29],[112,-178],[-397,-134],[371,-263],[-323,-218],[350,-220],[-65,-73],[340,-214],[-36,-222],[352,-113],[-19,-55]],[[31218,58337],[-354,-538],[-423,-550],[-664,-729]],[[40699,56878],[-36,-315],[-214,-341],[-510,-549],[141,-128],[-82,-131],[-391,-276]],[[41884,57869],[-538,-103],[-348,-1034],[-299,146]],[[42688,56015],[49,76],[-243,116],[31,122],[-293,82],[65,372],[-481,178],[72,283],[148,255],[-171,98],[124,206],[-105,66]],[[40965,53520],[-25,-91],[208,-160]],[[39607,55138],[180,-121],[-31,-173],[333,-370],[395,4],[29,-145],[221,-94],[-83,-252],[408,-201],[-94,-266]],[[38095,55925],[35,455],[-381,82],[21,60]],[[37770,56522],[-160,47],[29,291],[-232,69],[113,341],[-425,206],[-11,-191],[-174,81],[-119,-306],[-325,58],[-324,152],[-3,-132],[-197,65],[-57,226]],[[38764,57331],[987,-331],[124,368],[627,-312],[197,-178]],[[40422,59258],[-175,-313],[-503,17],[-91,-70],[75,-228],[-600,328],[-250,-252],[-164,-534],[192,-30],[-142,-845]],[[42196,60075],[-201,-53],[-135,-437],[-556,-17],[-426,-122],[-456,-188]],[[43058,59716],[-286,138],[-337,378],[-239,-157]],[[41884,57869],[98,178],[-144,130],[63,238],[281,102],[295,196],[87,166],[49,432],[123,179],[322,226]],[[36607,58974],[568,22],[131,341],[-247,160],[-174,200],[-385,268],[-278,124],[-278,-113],[-165,-202],[-367,328],[61,128],[-230,63],[-273,225],[69,73]],[[34156,60902],[56,-129],[-50,-272],[111,-229],[-142,-542],[-141,-160],[513,-444],[47,-211],[163,-143],[228,220],[179,-194],[37,-167],[-284,-321],[70,-157]],[[34527,60746],[-371,156]],[[35039,60591],[-512,155]],[[39501,51869],[-215,73],[-333,-110]],[[39324,50631],[224,328],[-43,426],[-80,140],[139,177],[-63,167]],[[39199,48982],[123,119],[51,225],[-201,347],[212,213],[-266,262],[74,207],[-70,247],[46,163],[156,-134]],[[36746,48763],[223,12],[420,324],[317,94],[391,-365],[194,-58],[52,185],[283,78],[171,236],[100,-286],[220,-94],[82,93]],[[36585,49848],[4,-250],[182,-300],[-121,-187],[96,-348]],[[37088,51256],[-463,-211],[-147,-240],[23,-410],[70,-109],[14,-438]],[[35222,50731],[-148,196],[-105,472],[252,160],[-258,133],[92,351],[-302,-48],[-33,301],[-216,32],[-77,481],[-347,93],[30,187]],[[33854,49652],[-6,51],[648,29],[-21,154],[306,85],[-33,382],[386,53],[88,325]],[[32200,51964],[130,-502],[81,-482],[92,-199],[-54,-224],[312,45],[189,-681],[-34,-187],[374,-78],[564,-4]],[[24419,56482],[-224,118],[-163,-222],[-695,-372],[-539,-839]],[[29777,56520],[-268,223],[-341,391],[-171,71],[-228,-122],[-340,22],[-259,-119],[-645,-154],[-2361,388],[-36,-92],[-709,-646]],[[30820,52698],[259,205],[164,244]],[[29286,52332],[152,35],[129,199],[264,-152],[137,359],[172,3],[217,241],[109,3],[192,-271],[162,-51]],[[22798,55167],[273,35],[583,187],[534,62],[379,-3],[195,-84],[548,-123],[576,-39],[268,-75],[719,-327],[576,0],[209,-365],[479,-460],[-47,-100],[518,-325],[168,-177],[-301,-210],[219,-217],[166,-270],[285,-318],[141,-26]],[[38727,54534],[218,324],[265,8],[397,272]],[[38764,57331],[-114,-193],[-88,-581],[-724,133],[-68,-168]],[[29370,52132],[124,143],[147,-206],[232,-91],[194,278],[187,7],[253,308],[313,127]],[[29286,52332],[84,-200]],[[43313,48704],[-161,290],[80,313],[144,295]],[[41331,47678],[198,13],[0,552],[389,88],[238,170],[373,-17],[-8,185],[475,-111],[51,188],[266,-42]],[[41155,50187],[10,-273],[-223,-951],[148,-42],[-58,-243],[96,-25],[-75,-480],[144,-35],[-84,-322],[210,-14],[8,-124]],[[43376,49602],[-306,173],[-322,-5],[-14,-80],[-669,336],[-9,120],[-391,36],[-168,-73],[-342,78]],[[31648,59194],[-430,-857]],[[32395,59800],[-235,-128],[-512,-478]],[[32644,59823],[-249,-23]],[[34111,60921],[-304,12],[-215,-191],[-120,-208],[-485,-384],[-343,-327]],[[34156,60902],[-45,19]],[[27949,61023],[-613,-185],[-617,-328],[-705,-195],[-201,350],[-617,448],[-630,-326]],[[28548,61142],[-599,-119]],[[31648,59194],[-1364,854],[-788,518],[-634,284],[-314,292]],[[24566,60787],[-194,-683],[47,-331],[-37,-216],[65,-242],[-69,-157],[131,-911],[-66,-382],[-213,-323],[-10,-255],[124,-343],[75,-462]],[[27580,49631],[396,141],[48,-64],[322,147],[246,214],[47,189],[277,231],[112,468],[-52,166],[167,203],[-8,141],[203,91],[71,230],[-39,344]],[[20119,50485],[-19,-73]],[[22798,55167],[-365,-603],[277,-87],[415,-212],[-1181,-1182],[-716,-501],[-1249,-1194],[378,-462],[-144,-170],[-94,-271]],[[41342,62304],[-1018,264],[-31,-383],[-218,64],[-44,235],[-94,-32],[-285,-622],[-680,-1066],[-234,-214],[117,-82],[14,-199],[-93,-211],[-359,-128]],[[42196,60075],[-123,36],[-277,-162],[-471,154],[71,84],[152,557],[-156,86],[41,403],[-91,1071]],[[38417,59930],[578,-209],[502,-287],[277,-53],[642,-33],[6,-90]],[[39501,51869],[-33,127],[122,230],[-16,193],[183,-11],[232,358],[91,232],[135,-67],[154,303],[112,-55],[101,261],[157,-77],[113,213],[113,-56]],[[41264,50634],[308,-53],[-17,462],[-283,-7],[73,249],[198,-32],[-84,444],[37,114]],[[39324,50631],[3,-120],[312,-34],[571,110],[17,112],[365,-154],[-3,211],[675,-122]],[[41342,62304],[-44,832]],[[36700,60778],[203,-113],[-52,-178],[276,-66],[198,-144],[-37,-88],[808,-462],[97,134],[224,69]],[[41298,63136],[-895,265],[-39,-371],[-455,69],[-399,-237],[-371,56],[-224,-418],[-264,-352],[-110,-246],[-506,-118],[-167,-216],[-48,157],[-98,-307],[-60,-414],[-269,307],[-389,-618],[-304,85]],[[36155,61081],[-301,168]],[[36700,60778],[-70,-20],[-475,323]],[[35854,61249],[-28,-98],[-368,1],[-419,-561]],[[35222,50731],[357,-94],[26,-133],[292,89],[30,-103],[530,-91],[-20,-173],[148,-378]],[[43767,49844],[142,82],[102,435],[128,220],[55,384]],[[43376,49602],[92,391],[174,25],[125,-174]],[[41264,50634],[-109,-447]],[[41328,47404],[3,274]],[[39429,47180],[384,-178],[535,251],[572,-72],[148,247],[260,-24]],[[39199,48982],[45,-51],[-96,-580],[-132,-397],[172,-41],[-67,-210],[105,-46],[23,-395],[180,-82]],[[46756,55393],[-77,-250],[-202,-172],[-209,185],[140,308],[-234,16],[-255,125],[-76,-162],[-233,54],[-15,-150],[-218,96],[-194,-263],[-72,-217],[-465,306],[-17,-50]],[[49491,55016],[-440,230],[-310,215],[-443,-6],[-150,-279],[-463,137],[-153,117],[-426,-194],[-350,157]],[[48975,53843],[170,328],[131,96],[-17,300],[189,244],[43,205]],[[48666,52898],[6,239],[156,400],[-58,168],[205,138]],[[47677,52316],[72,99],[264,677],[405,-131],[103,-141],[145,78]],[[45106,53280],[507,-26],[770,-113],[80,145],[140,-74],[-27,-277],[262,-70],[209,-170],[45,-139],[250,11],[335,-251]],[[55420,63774],[157,430]],[[54340,61139],[122,132],[112,388],[150,7],[167,189],[120,404],[-30,162],[291,402],[79,325],[-58,238],[172,180],[-45,208]],[[53223,62475],[265,-293],[-39,-77],[439,-489],[50,-156],[402,-321]],[[53971,64974],[-66,-225],[229,-297],[-85,-305],[-49,-467],[-214,-150],[29,-248],[-165,-305],[-154,-100],[-103,-263],[-170,-139]],[[54793,65454],[-255,-268],[-69,-311],[-498,99]],[[55577,64204],[-94,129],[-278,153],[-72,-105],[12,381],[98,265],[-43,169],[-199,-21],[-20,190],[-188,89]],[[51017,51962],[210,423],[53,-32],[347,651],[416,162],[115,213],[252,-109],[74,-133],[333,-224],[83,205]],[[50277,51765],[92,13],[158,390],[431,-103],[59,-103]],[[48975,53843],[315,-384],[251,-171],[54,-317],[-240,-361],[96,-212],[228,5],[-95,-229],[693,-409]],[[49822,55740],[-212,-183],[-119,-541]],[[51619,55202],[-188,-385],[-98,36],[-367,394],[-638,322],[-110,-232],[-379,284],[-17,119]],[[52900,53118],[87,427],[-248,234],[-514,364],[-160,-7],[-293,174],[5,330],[87,402],[-245,160]],[[48666,52898],[-162,-271],[-10,-307],[-226,-326],[7,-668],[45,-117],[215,82],[137,-203],[-6,-269],[244,-126]],[[49909,51122],[161,-14],[394,216],[-187,441]],[[48910,50693],[289,-7],[75,161],[177,6],[137,199],[107,-52],[55,178],[159,-56]],[[50210,48817],[-56,431],[-202,410],[-71,250],[10,339],[-262,214],[-77,-56],[-205,253],[300,281],[254,75],[8,108]],[[47948,49217],[314,-13],[148,-284],[290,-225],[-65,-271],[137,-94],[-19,-215],[624,262],[195,201],[6,179],[135,166],[253,29],[244,-135]],[[47881,49279],[67,-62]],[[48910,50693],[-275,-22],[-71,-250],[-117,48],[-207,-705],[-159,59],[-67,-360],[-133,-184]],[[47567,57979],[-117,-251],[-354,442],[-481,-811]],[[50289,57849],[-124,-183],[-156,236],[-484,-231],[-637,484],[-178,-465],[-74,34],[57,270],[-400,229],[-190,-412],[-536,168]],[[49822,55740],[97,232],[-87,342],[-182,-16],[39,140],[370,343],[221,286],[321,624],[-203,192],[-109,-34]],[[46615,57359],[333,-302],[250,-113],[-234,-449],[-91,-812],[-117,-290]],[[48302,64427],[259,62],[132,484],[123,-39],[57,-202],[284,-251],[97,470],[231,-213],[18,-231],[240,45],[309,234],[479,-289]],[[47146,65169],[300,-7],[-208,-563],[328,-265],[213,-75],[154,203],[369,-35]],[[47521,66130],[-98,-238],[76,-38],[-177,-517],[-176,-168]],[[48721,69241],[-23,-740],[-123,-61],[-12,-511],[88,-229],[-115,-547],[72,-202],[-208,-207],[-173,-275],[-91,-328],[-296,92],[-91,-175],[-228,72]],[[49088,69804],[-9,-114],[-268,-233],[-90,-216]],[[50303,68386],[-461,469],[-37,310],[-282,463],[-188,134],[-247,42]],[[51348,66950],[-185,118],[-352,353],[-141,228],[-262,257],[36,336],[-141,144]],[[51183,65995],[49,383],[-145,52],[261,520]],[[50531,64497],[119,809],[318,652],[215,37]],[[46615,50761],[78,273],[234,353],[280,-43],[187,386],[60,-26],[223,612]],[[44986,51481],[416,-185],[-24,-154],[332,-149],[-43,-70],[948,-162]],[[53223,62475],[-451,387],[60,106],[-198,183]],[[54182,60957],[158,182]],[[53603,60287],[241,461],[168,-4],[170,213]],[[50740,58994],[410,354],[77,176],[-90,184],[547,52],[303,-162],[-18,-173],[597,-395],[262,53],[192,643],[233,194],[128,251],[222,116]],[[51020,61406],[286,63],[-1,-138],[-310,-364],[24,-220],[-310,-292],[36,-89],[-230,-369],[-222,-238],[-25,-375],[65,-163],[171,-13],[236,-214]],[[51342,62531],[-62,-207],[73,-222],[-211,-506],[-122,-190]],[[52634,63151],[-229,-125],[-193,-206],[-237,-12],[-275,-270],[-358,-7]],[[51017,51962],[177,-461],[97,91],[264,-12],[41,-397],[420,156],[363,-169],[-88,-254],[48,-121],[359,-154],[141,-245],[1019,-930],[520,25]],[[54322,52650],[-399,321],[-480,260],[-151,-183],[-392,70]],[[54779,51644],[94,196],[-210,181],[-260,328],[-142,42],[61,259]],[[54688,51082],[29,450],[62,112]],[[54378,49491],[106,540],[155,348],[73,330],[-24,373]],[[46821,49610],[283,18],[537,-387],[240,38]],[[46615,50761],[101,-366],[-45,-235],[176,-45],[-64,-310],[38,-195]],[[43824,59677],[-351,-23],[-158,-239],[-242,164],[-15,137]],[[44430,56641],[-183,97],[139,256],[-15,193],[104,159],[-248,269],[45,224],[229,326],[-189,220],[157,108],[-127,192],[-199,110],[-10,564],[-92,-13],[-2,247],[-215,84]],[[44088,55825],[203,452],[199,134],[-60,230]],[[51980,65924],[-132,-138],[-665,209]],[[53307,64830],[-159,-6],[71,277],[-357,285],[-788,516],[-94,22]],[[52634,63151],[86,342],[158,104],[-27,122],[391,591],[80,297],[-15,223]],[[50531,64497],[-68,-535],[117,-70],[-216,-502],[405,-265],[-72,-58],[410,-262],[235,-274]],[[47113,61169],[208,462],[141,422],[159,237]],[[44390,61884],[286,-211],[335,-588],[12,-134],[282,23],[695,-277],[15,308],[318,-84],[69,139],[184,-73],[269,172],[258,10]],[[44306,62120],[84,-236]],[[47777,63181],[-68,274],[89,281],[-194,117],[-29,-162],[-263,65],[-97,-135],[-110,82],[-158,-222],[65,-74],[-371,-6],[-115,91],[-183,-230],[-97,56],[-129,-208],[-292,145],[-423,12],[9,-96],[-496,-52],[-223,280],[-264,-179],[201,-745],[-83,-23],[-240,-332]],[[47621,62290],[133,396],[-73,364],[96,131]],[[53807,55683],[-301,93],[106,198],[-233,112],[-181,-28],[-540,327],[-363,145],[-104,104],[-175,-313],[-151,66],[-331,-363],[96,-235],[-199,-234],[188,-353]],[[54322,52650],[138,375],[-65,295],[-187,216],[-214,127],[45,297],[-134,212],[70,362],[-43,393],[-78,70],[54,259],[-91,46],[-10,381]],[[53971,64974],[-75,690],[-115,247],[-365,-434],[-124,-524],[15,-123]],[[46615,57359],[-376,105],[-190,113],[-304,-13],[-187,-306],[-237,117],[-52,-233],[-206,55],[-138,-480],[-236,144],[-259,-220]],[[47113,61169],[463,-318],[151,-308],[102,128],[507,-310],[-15,-255],[-195,-270],[-313,-148],[-348,-364],[519,-165],[-158,-364],[90,-29],[-349,-787]],[[51020,61406],[-611,-341],[-245,-272],[-415,61],[-91,-480],[-628,12],[16,363],[-649,41],[10,314],[-226,-35],[64,169],[-296,73],[-91,114],[-42,590],[153,182],[-348,93]],[[50289,57849],[240,231],[-100,518],[143,280],[168,116]],[[48302,64427],[-12,-472],[-110,-120],[-174,-634],[-229,-20]],[[53807,55683],[-19,503],[170,226],[275,153],[150,253],[73,438],[124,330],[-315,349],[306,519],[87,19]],[[54658,58473],[-14,280],[-290,-6],[-515,336],[72,148],[-61,256],[59,259],[-57,228],[-148,49],[-101,264]],[[44390,61884],[104,-378],[19,-389],[-196,-205],[-123,-368],[-118,-85],[18,-576],[-222,43],[-48,-249]],[[52726,85699],[-259,34],[-137,653]],[[52760,85578],[-34,121]],[[54072,78902],[-915,1581],[-162,238],[-65,-43],[-404,599],[171,267],[-313,461],[-224,459],[189,287],[218,193],[-386,600],[-255,1114],[-70,4],[-23,376],[366,90],[-83,390],[644,60]],[[53514,78562],[558,340]],[[51492,80314],[331,246],[445,-221],[94,-177],[385,-276],[767,-1324]],[[50519,82642],[432,-401],[-26,-296],[-162,-57],[72,-409],[120,-111],[-148,-93],[307,-493],[109,21],[44,-219],[225,-270]],[[50717,85907],[-453,20],[-466,-51],[561,-215],[151,-397],[-119,-88],[115,-483],[437,341],[185,-61],[-207,-393],[-3,-287],[-127,-321],[106,-436],[28,-376],[-257,-26],[-149,-492]],[[52330,86386],[-26,103],[-439,-95],[-292,-122],[-430,-298],[-426,-67]],[[42101,79314],[131,89]],[[40408,83775],[-272,-197],[-527,-655],[-23,-314],[-222,-289],[-109,-760],[170,7],[666,-548],[-16,-314],[116,-643],[691,-733],[121,-250],[357,-5],[741,240]],[[43970,85800],[-640,-485],[-614,-386],[-202,-188],[131,-132],[-225,-90],[-497,-301],[-340,-363],[-152,159],[-252,-261],[-368,-88],[-129,-132],[-274,242]],[[44244,85037],[195,230],[-390,597],[-79,-64]],[[44918,82043],[337,243],[-57,302],[-126,-34],[-460,174],[-145,184],[90,196],[325,338],[-226,331],[-120,-22],[-201,324],[-322,-185],[2,241],[-143,215],[257,195],[-43,277],[158,215]],[[43980,81397],[938,646]],[[42232,79403],[286,491],[274,323],[215,465],[-16,234],[982,583],[7,-102]],[[50519,82642],[-262,-50],[54,-129],[-148,-68],[-135,410],[-952,-146],[64,-470],[-39,-270],[-152,-303]],[[49297,80229],[478,170],[374,-161],[318,-61],[61,-128],[469,-112],[359,91],[165,-23],[-29,309]],[[48971,81224],[-23,-95],[122,-509],[186,-184],[41,-207]],[[48949,81616],[121,-286],[-99,-106]],[[53369,86869],[-1039,-483]],[[57481,86697],[-265,53],[-201,-201],[-215,-64],[-112,-220],[-604,-309],[-235,179],[-476,655],[-565,368],[-409,-71],[-159,118],[-294,-80],[-577,-256]],[[57627,80280],[3203,3108],[-2034,2201],[-392,92],[-886,114],[-451,-361],[-171,-88],[125,431],[231,250],[229,670]],[[52726,85699],[259,68],[264,-101],[154,121],[127,-277],[339,-30],[329,-1066],[175,-125],[101,-333],[242,118],[-14,-161],[197,-241],[130,-283],[300,-257],[198,-465],[2100,-2387]],[[54994,79463],[2633,817]],[[52760,85578],[27,-121],[349,52],[177,-582],[101,-128],[-492,-226],[112,-329],[320,-526],[240,-607],[385,-603],[-168,-152],[579,-1079],[604,-1814]],[[42708,86391],[-248,-179],[-662,-124],[-199,-145],[-281,-325],[-609,-286],[-111,-2],[-308,-367],[-301,-437],[-258,-203]],[[43970,85800],[-208,149],[-563,199],[-185,133],[-146,-121],[-160,231]],[[39731,84323],[677,-548]],[[48971,81224],[-210,66],[-335,-67],[-133,-242],[-761,-210],[-614,-245],[29,-100],[-296,-59],[-186,-351]],[[47889,79607],[354,-29],[245,239],[327,130],[239,25],[243,257]],[[46465,80016],[296,-250],[397,-230],[527,-16],[204,87]],[[44244,85037],[121,-259],[297,-337],[337,-89],[338,-828],[240,-105],[396,-465],[-17,-137],[498,-666],[434,110],[174,-364],[-108,-49],[202,-336],[-223,-100],[-331,4],[-398,-111],[-145,-164]],[[44753,87448],[-1039,-449],[-1006,-608]],[[47180,83264],[-443,-181],[-138,5],[-228,-146],[135,266],[-348,324],[65,445],[-135,226],[-134,50],[-233,-117],[-266,345],[90,128],[-85,132],[194,100],[-81,154],[306,210],[289,118],[32,225],[-263,431],[-1045,556],[142,77],[-221,428],[81,161],[-119,32],[-22,215]],[[48949,81616],[-152,201],[-134,-112],[-17,164],[-276,14],[-6,-119],[-282,-87],[-400,282],[-219,-96],[-297,965],[113,149],[-99,287]],[[46136,79989],[329,27]],[[46059,81141],[125,-655],[-137,12],[89,-509]],[[46136,79989],[-500,147],[-320,-74]],[[47317,77208],[45,358],[382,213],[321,94],[-193,180],[-53,509],[-73,293],[305,367],[240,60],[29,175],[-461,9],[30,141]],[[45461,77678],[76,-171],[840,292],[93,-452],[529,193],[85,-407],[233,75]],[[45257,79795],[109,-184],[-332,-155],[284,-521],[246,11],[-36,-154],[-198,-74],[77,-253],[36,-410],[-198,-191],[244,-71],[-28,-115]],[[45316,80062],[-59,-267]],[[44918,82043],[528,-621],[137,-320],[476,39]],[[50229,76563],[3285,1999]],[[48735,76351],[1494,212]],[[47477,76250],[119,71],[294,-11],[353,-175],[492,216]],[[47317,77208],[159,-470],[1,-488]],[[46377,87743],[-667,-374],[-439,97],[-518,-18]],[[47180,83264],[443,90],[-158,336],[561,237],[119,129],[-53,310],[-239,-33],[-174,290],[-109,413],[524,214],[-214,462],[-276,-198],[-448,-235],[-50,111],[-267,-53],[-193,338],[275,197],[-168,429],[-28,351],[-111,156],[-365,318],[-18,340],[146,277]],[[57365,87369],[-178,57],[-222,194],[-290,-65],[-240,127],[-381,66],[-157,95],[-366,27],[-584,-158],[-59,-73],[-221,101],[-746,-176],[-452,-211],[-296,132],[-152,-101],[348,-515]],[[57481,86697],[101,558],[-217,114]],[[43980,81397],[415,-681],[90,73],[129,-435],[188,32],[-75,-364],[189,86],[178,-84],[222,38]],[[54072,78902],[922,561]],[[48361,88340],[439,-802],[772,-939],[627,-450],[518,-242]],[[57365,87369],[187,1280],[-1115,901],[-471,435],[-358,90],[94,704],[-13,519],[289,1243],[243,659],[-152,79],[-137,259],[55,286],[-437,-159],[-2171,-933],[-478,-194],[-345,-189],[-957,-424],[-1150,-793],[-71,-92],[-571,-329],[-151,-566],[-1295,-1805]],[[39753,77872],[288,151],[1155,-57],[475,402],[234,349],[-67,101],[263,496]],[[31884,77268],[200,398],[478,461],[63,189],[365,-338],[141,-263],[711,-1010],[416,-657],[244,-33],[108,-174],[411,100],[1320,675],[186,216],[276,169],[630,296],[1068,299],[744,288],[231,52],[277,-64]],[[39731,84323],[-356,-264],[-753,-213],[-836,-292],[-1873,-699],[-952,79],[-350,92],[-92,377],[-446,64],[-1440,-2305],[-319,-1088],[98,-1021],[-825,-422],[297,-1363]],[[48361,88340],[-263,-361],[-1042,36],[-679,-272]],[[53971,44188],[-185,-65],[-43,-176],[-377,-336],[-243,64],[-188,-71],[-247,-210],[-295,-464],[-317,-334],[-451,-187],[-138,-312],[-189,-130],[47,-315],[202,-646]],[[54700,43922],[-106,123],[-252,-8],[-75,209],[-296,-58]],[[51706,41079],[335,273],[92,168],[357,300],[122,-69],[198,187],[210,33],[130,617],[155,240],[161,20],[276,302],[169,381],[376,144],[-12,62],[425,185]],[[51547,41006],[159,73]],[[44712,48441],[170,302],[452,403],[40,158],[334,313],[486,-192],[471,201],[156,-16]],[[43767,49844],[-229,-217],[-176,-476],[54,-245],[166,-67],[135,214],[73,-65],[56,312],[216,-306],[-160,-158],[-226,-29],[136,-149],[391,108],[509,-325]],[[44241,45908],[-206,6],[116,275],[-62,145],[66,617],[151,531],[136,118],[74,390],[196,451]],[[44457,45112],[-84,608],[-132,188]],[[43468,44253],[165,82],[160,258],[25,507],[201,151],[383,-182],[55,43]],[[42497,44895],[347,-154],[624,-488]],[[42394,46922],[30,-237],[249,-209],[-162,-751],[132,-521],[-357,-124],[261,-114],[-50,-71]],[[43313,48704],[-29,-213],[-145,-270],[-43,-298],[-375,-353],[76,-220],[-227,-97],[-176,-331]],[[50542,46887],[-105,-287],[-140,-131],[47,-354],[-160,-397],[41,-185],[-151,-236],[-459,-49],[-120,86],[-172,-118]],[[49323,45216],[216,-224],[330,-159],[195,-231],[193,102],[18,-133],[293,-26],[549,-331],[506,-117],[127,347],[120,81],[10,231],[101,196],[244,171],[299,348],[-38,213],[164,231],[28,199],[-80,251],[-369,-72],[-155,144],[-94,-116],[-429,347],[-346,454],[162,292],[248,112],[-391,177],[-476,-302],[-210,-304],[4,-210]],[[45162,47249],[-121,19],[-293,-373],[-239,-442],[-91,-355],[-177,-190]],[[45835,45733],[-57,274],[-171,-33],[44,407],[-145,165],[-213,85],[-12,641],[-119,-23]],[[45100,44755],[692,343],[-166,157],[-3,272],[212,206]],[[44457,45112],[204,88],[439,-445]],[[44464,42877],[-207,-242],[-92,-415],[86,-183],[-226,-12]],[[45536,42492],[-237,-162],[-342,115],[-493,432]],[[46427,45669],[-95,-662],[31,-577],[-124,-42],[214,-563],[-99,-179],[-369,-306],[10,-376],[-289,58],[-80,-267],[51,-214],[-141,-49]],[[47066,45789],[-219,-49],[-237,-210],[-183,139]],[[49323,45216],[-282,-108],[-87,-274],[-253,2],[-237,-250],[-144,81],[-299,-97],[-46,-204],[-171,-124],[-107,297],[-171,0],[31,213],[-97,224],[-191,126],[-79,414],[-120,29],[-4,244]],[[50210,48817],[21,-139],[193,8],[-77,-242],[93,-389],[11,-315],[-184,-335],[-56,-342],[331,-176]],[[55342,48384],[97,699],[148,279],[-844,108],[-365,21]],[[53640,44656],[15,294],[185,408],[-49,123],[100,237],[235,136],[113,352],[143,232],[19,235],[143,214],[141,600],[228,95],[429,802]],[[48688,33737],[176,6259],[8,112],[-193,334],[-28,237],[472,280],[730,66],[59,225],[-6,378],[460,295],[72,320],[182,123],[193,293],[321,-10],[22,282],[120,-24],[-8,478],[265,194],[350,37],[185,309],[73,-23],[387,171],[545,840],[135,-3],[254,-268],[178,14]],[[44006,33876],[4682,-139]],[[44025,42025],[199,-420],[-218,-7729]],[[46898,47660],[496,340],[367,442],[181,415],[6,360]],[[45162,47249],[-162,352],[168,284],[227,-49],[81,298],[957,-79],[-9,-160],[452,-19],[22,-216]],[[46898,47660],[-120,-72],[28,-339],[205,-207],[7,-461],[-152,-290],[200,-502]],[[51553,33652],[174,6214],[2,605],[217,174],[23,143],[-263,291]],[[50871,33673],[682,-21]],[[51547,41006],[-268,-489],[22,-138],[-256,-517],[-174,-6189]],[[46427,45669],[-232,38],[-54,154],[-255,34],[-51,-162]],[[45100,44755],[70,-147],[-195,-178],[274,-124],[-62,-355],[62,-300],[24,-463],[114,-84],[-50,-192],[125,-132],[-80,-159],[154,-129]],[[53971,44188],[-124,340],[-207,128]],[[48688,33737],[2183,-64]],[[43435,44153],[170,-200],[-16,-204],[212,-67],[-77,-296],[-230,-177],[92,-159],[297,81],[581,-254]],[[43468,44253],[-33,-100]],[[60132,36663],[295,38],[231,-344],[302,-275]],[[61160,37956],[-88,158],[-164,-1],[-292,136],[-10,-90],[-252,47],[41,257],[-146,-143],[-245,97],[-30,-796],[-143,176],[-270,-7],[-79,-237],[-401,1],[-47,-65],[595,-380],[193,-218],[222,38],[-28,-160],[116,-106]],[[60960,36082],[255,20],[145,407],[-177,213],[40,110],[-337,184],[117,101],[370,-100],[-58,281],[-141,212],[-14,446]],[[55769,42021],[1421,-1344],[1255,-683]],[[57900,47817],[-87,-211],[-291,61],[-164,-301],[19,-360],[548,-316],[78,137],[44,-288],[444,-327],[-90,-218],[-361,-334],[140,-348],[141,-145],[-191,-147],[159,-112],[-448,-400],[95,-104],[-138,-185],[42,-100],[-318,-461],[85,-47],[-604,-443],[45,-95],[-249,-251],[-138,46],[-100,-150],[-511,-469],[20,-146],[-301,-82]],[[60198,46958],[-819,339],[-492,259],[-184,-380],[-433,390],[-370,251]],[[62487,45257],[-570,267],[-565,545],[85,196],[-448,61],[-540,486],[-251,146]],[[58445,39994],[98,218],[90,529],[415,1058],[806,431],[60,127],[230,-153],[448,389],[-44,82],[217,282],[163,414],[472,462],[147,306],[173,205],[204,391],[563,522]],[[55417,41595],[-272,21],[-47,93],[164,263],[-65,163],[108,152],[-161,126],[-160,337],[256,231],[-342,191],[-236,285],[-123,53],[226,111],[-65,301]],[[52533,33524],[1521,5387],[213,263],[37,334],[412,841],[416,448],[82,321],[203,477]],[[51553,33652],[612,-18],[368,-110]],[[63226,42492],[-151,38],[-342,347],[-207,70],[224,274],[267,748],[7,218],[179,271],[93,330],[-231,183],[-578,286]],[[64223,40745],[-138,255],[-379,303],[-228,613],[-372,469],[120,107]],[[62066,36765],[-144,200],[140,424],[267,-133],[117,97],[335,22],[96,78],[-106,403],[169,327],[-157,124],[-19,567],[104,303],[221,7],[38,167],[346,539],[134,338],[-41,206],[148,158],[352,30],[157,123]],[[61160,37956],[333,-485],[182,-482],[188,-221],[203,-3]],[[58970,31596],[1287,4530],[-69,255],[-166,134],[110,148]],[[56522,32329],[2448,-733]],[[58445,39994],[-165,-590],[5,-474],[-38,-700],[-155,-252],[-74,-372],[-1496,-5277]],[[59635,31397],[1320,4635],[5,50]],[[58970,31596],[665,-199]],[[60702,31077],[1336,4692],[36,469],[-8,527]],[[59635,31397],[1067,-320]],[[57424,48504],[-233,-111],[-561,-24],[-279,-338],[-299,471],[-205,39],[-505,-157]],[[57900,47817],[-105,105],[-371,582]],[[55417,41595],[45,-42],[307,468]],[[52533,33524],[3989,-1195]],[[39248,47113],[85,-156]],[[36823,47038],[157,381],[302,-131],[161,-195],[348,-115],[55,152],[210,-34],[20,-112],[559,-8],[158,36],[85,358],[313,-129],[57,-128]],[[36537,47093],[286,-55]],[[36746,48763],[-165,-123],[-164,-288],[123,-153],[-79,-89],[323,-211],[-179,-416],[-68,-390]],[[39333,46957],[96,223]],[[39944,45968],[-306,256],[64,89],[-170,140],[-276,442],[77,62]],[[38786,44414],[62,216],[103,-22],[181,400],[230,2],[-23,380],[302,17],[-143,231],[446,330]],[[37567,44503],[155,43],[235,231],[87,-124],[577,-224],[165,-15]],[[37505,45502],[-94,-108],[-283,-583],[194,-187],[245,-121]],[[39248,47113],[-199,-125],[-56,-305],[-429,-268],[-289,-475],[-6,-148],[-506,61],[-98,-345],[-160,-6]],[[34160,31354],[-2706,4544],[-60,288],[-182,220],[-386,1]],[[30509,29069],[3651,2285]],[[28980,36295],[-59,-318],[76,-220],[-224,-275],[-199,6],[-66,-203],[-444,-118],[-146,-125],[-229,-427],[2820,-5546]],[[30826,36407],[102,-308],[-364,-55],[-628,17],[-522,189],[-126,111],[-308,-66]],[[42394,46922],[-117,-220],[-128,372],[-170,193],[-206,-14],[-7,109],[-438,42]],[[41240,44656],[488,-98],[48,-144],[91,216],[292,195],[277,-11],[61,81]],[[39944,45968],[273,-33],[79,-161],[113,176],[77,-389],[279,-184],[-35,-182],[252,-63],[128,-182],[114,86],[72,-243],[-56,-137]],[[43435,44153],[-164,-395],[-251,121],[-489,-969],[18,-461],[191,-248],[570,102],[188,179],[326,79],[103,-118],[-35,-167],[133,-251]],[[34435,41260],[325,-568]],[[35336,42150],[-376,120],[-391,-72],[-104,-301],[118,-345],[-148,-292]],[[34953,40944],[245,324],[222,-155],[169,161],[150,-138],[110,106],[-432,313],[-210,86],[109,210],[20,299]],[[34760,40692],[193,252]],[[32757,44526],[530,637],[-50,115]],[[32669,46983],[-207,-33],[53,-330],[-49,-538],[-285,-306],[152,9],[196,-441],[-62,-255],[93,-32],[-107,-354],[304,-177]],[[33237,45278],[-16,174],[-236,197],[-143,454],[94,97],[-5,382],[-213,192],[-49,209]],[[31805,41947],[78,-111],[-113,-146],[263,-313],[-121,-111],[98,-125],[-193,-126],[276,-155],[159,-179]],[[31584,42408],[357,-389],[-136,-72]],[[33226,42956],[-632,-278],[-471,-263],[-178,195],[-361,-202]],[[34171,41367],[105,205],[-215,228],[174,256],[-716,549],[-293,351]],[[33084,40596],[540,385],[262,109],[285,277]],[[32252,40681],[280,-6],[192,135],[200,-182],[160,-32]],[[39561,42499],[165,-260],[111,-329],[-122,-237],[202,-40],[-13,-225],[538,-231]],[[39654,43353],[-154,-128],[300,-310],[-296,-101],[57,-315]],[[40842,43169],[-140,189],[-412,-267],[-166,55],[-20,164],[-190,-74],[14,181],[-274,-64]],[[40449,41188],[213,170],[-126,203],[230,326],[-71,211],[126,195],[-14,181],[-129,44],[273,357],[46,207],[-155,87]],[[40442,41177],[7,11]],[[38786,44414],[232,8],[14,-168],[-163,-74],[32,-305],[115,-188],[154,-46],[94,123],[390,-411]],[[40842,43169],[454,303],[70,412],[-175,30],[74,210],[-71,356],[46,176]],[[33733,48006],[-469,-483],[-326,-177],[-10,-352],[-146,131],[-113,-142]],[[36537,47093],[-168,-821],[-333,131],[40,324],[-198,-3],[-357,266],[42,150],[-528,296],[-228,172],[-32,-221],[-105,23],[47,313],[-441,100],[-54,-145],[-430,151],[-59,177]],[[37505,45502],[40,125],[-274,107],[185,491],[-120,129],[-226,-26],[-206,100],[78,350],[-158,106],[-1,154]],[[37562,42387],[-42,298],[-184,93],[113,534],[-150,40],[76,251],[-83,53],[112,204],[127,-76],[-44,225],[80,494]],[[35340,42449],[141,-290],[238,96],[298,-17],[269,141],[287,50],[110,-115],[390,55],[119,110],[103,-179],[267,87]],[[34731,43256],[109,-13],[119,-356],[221,-116],[-38,-94],[198,-228]],[[33237,45278],[332,6],[158,-265],[410,268],[398,-149],[14,-285],[90,43],[107,-197],[-127,-42],[61,-285],[-85,-114],[205,-158],[-82,-152],[117,-326],[-104,-366]],[[40449,41188],[371,95],[339,-83],[628,20],[494,303],[634,115],[563,239],[547,148]],[[29001,37160],[75,-331],[-71,-250],[142,-117],[-167,-167]],[[30528,39365],[10,-239],[-666,-469],[-85,162],[-464,-323],[100,-150],[-97,-490],[-159,49],[-26,-186],[-176,-177]],[[31480,39173],[-250,-70],[-214,-148],[-201,371],[-287,39]],[[30826,36407],[-27,230],[400,219],[-125,182],[388,313],[-252,365],[200,146],[-96,153],[479,288],[-301,435],[153,149],[-165,286]],[[29819,40847],[-337,165],[-164,-108],[-530,317]],[[30528,39365],[-283,414],[-236,464],[-266,225],[76,379]],[[38056,41675],[4,166],[316,207],[456,67],[433,270],[296,114]],[[37562,42387],[37,-160],[344,-466],[113,-86]],[[34997,38847],[-49,193],[-222,-48],[-77,221],[-445,547],[144,114],[-139,193],[551,625]],[[33685,39472],[479,-238],[-308,-155],[84,-150],[578,-428],[280,145],[199,201]],[[33084,40596],[84,-110],[-120,-322],[553,-466],[-58,-215],[142,-11]],[[34435,41260],[-113,-167],[-151,274]],[[31504,39469],[236,-134],[91,-273],[889,-387],[291,109],[270,349],[190,99],[214,240]],[[32252,40681],[-217,-399],[-233,-89],[-140,107],[-132,-388],[50,-135],[-132,-121],[56,-187]],[[39330,34013],[-1297,7366],[23,296]],[[38451,34039],[879,-26]],[[34953,40944],[428,-649],[-64,-32],[479,-543],[2655,-5681]],[[35340,42449],[-4,-299]],[[40057,33992],[180,6388],[131,255],[264,94],[50,159],[-352,49],[112,240]],[[39330,34013],[727,-21]],[[31504,39469],[-131,-132],[107,-164]],[[37983,33746],[-2803,4706],[-183,395]],[[34160,31354],[3823,2392]],[[40057,33992],[3949,-116]],[[37983,33746],[468,293]],[[32757,44526],[-159,-233],[237,-45],[148,129],[210,-85],[233,-357],[-97,-64]],[[33329,43871],[116,-198],[277,69],[221,-174],[161,36],[495,-378],[132,30]],[[31805,41947],[-110,-13],[-108,-527],[-351,251],[-308,-434],[-73,157],[-289,-43],[92,-173],[-132,-10],[-248,-230],[-406,58],[-53,-136]],[[33329,43871],[-358,-373],[-47,-203],[302,-339]],[[33854,49652],[46,-396],[-125,-18],[57,-318],[-179,-78],[40,-402],[227,-264],[-187,-170]],[[31584,42408],[-496,413],[-147,44],[-366,464],[-122,-88],[-62,219],[-153,135],[62,218],[-75,149],[-482,60],[-664,444],[-488,79],[2,49]],[[54182,60957],[36,-142],[238,-158],[284,125],[141,-87],[38,-299],[104,-190],[-115,-283],[325,194],[288,-20],[96,202],[-119,65],[130,264],[120,-58],[134,274],[220,-113],[174,562],[326,91],[137,-138],[125,38],[61,245],[-391,-21],[55,238],[-119,13],[-129,-252],[-148,79],[245,279],[-74,106],[-13,322],[-220,531],[-322,192],[-26,423],[-242,305],[-121,30]],[[62808,63875],[-196,-155],[-198,-298],[-448,-552],[-176,-75],[-128,-202]],[[64533,63266],[-69,209],[-241,335],[-47,-46],[-276,201],[-78,-75],[-160,140],[87,164],[-225,26],[-208,152],[-508,-497]],[[61662,62593],[118,28],[315,-450],[397,-12],[85,-175],[248,-48],[436,94],[495,301],[442,534],[215,362],[120,39]],[[66030,59328],[148,423],[-230,384],[-400,294],[-862,-124],[107,401],[-102,213],[-235,217]],[[62226,57900],[259,-37],[425,208],[533,-136],[94,-259],[330,39],[-101,180],[305,317],[329,636],[226,363],[127,91],[208,-93],[169,299],[242,-96],[178,136],[480,-220]],[[62177,57878],[49,22]],[[64456,61136],[-384,-292],[-190,-77],[-66,-330],[-306,-214],[-108,-203],[-303,-135],[-7,-84],[-308,-275],[-478,-582],[-216,-583],[87,-483]],[[65541,62151],[181,-239],[110,225],[366,446],[128,89],[67,289],[203,-79],[-67,161],[188,-54],[127,116]],[[64765,63134],[520,-400],[246,-339],[10,-244]],[[67468,66649],[-106,-335],[-382,-448],[-85,-206],[-410,-626],[-161,-351],[-289,180],[-433,-309],[-15,-189],[104,-505],[-409,-98],[-149,-122],[-368,-506]],[[67967,66266],[-195,302],[-12,139],[-145,-187],[-147,129]],[[67981,64720],[93,217],[-170,144],[178,280],[-62,58],[191,191],[-115,143],[155,187],[-357,175],[73,151]],[[66844,63105],[-34,838],[430,-218],[189,391],[134,18],[157,263],[46,260],[215,63]],[[68496,64646],[196,258],[274,-189],[271,-108],[77,210],[241,-42],[52,-136],[113,159],[392,-283]],[[67981,64720],[127,-49],[115,135],[273,-160]],[[70602,65244],[-398,192],[81,248],[-217,59],[86,247],[-204,103],[-119,-214],[-75,404],[-423,183],[-115,180],[-184,25],[-77,208],[-165,-136],[-295,8],[-376,-182],[-154,-303]],[[70112,64515],[180,371],[181,97],[129,261]],[[58133,54764],[77,210],[280,190],[-95,272],[466,271],[183,-52]],[[57117,54760],[301,-218],[229,179],[139,-47],[347,90]],[[59099,58293],[-5,-112],[-233,-213],[-431,-9],[-487,-758],[-328,-431],[-276,-18],[42,-141],[-20,-453],[-256,-320],[114,-171],[-102,-907]],[[59557,58102],[-458,191]],[[60003,57809],[-446,293]],[[59363,55877],[219,365],[-79,110],[119,375],[220,210],[-105,234],[108,63],[21,321],[137,254]],[[59044,55655],[319,222]],[[66844,63105],[127,-555],[225,-558],[133,-123],[181,-402],[-5,-141],[262,-68]],[[69153,62956],[-204,185],[-258,-412],[-352,150],[657,870],[-263,202],[149,201],[-460,354],[74,140]],[[67767,61258],[-153,580],[216,30],[-9,206],[270,349],[394,-303],[185,188],[483,648]],[[67468,66649],[139,273],[-91,59],[184,238],[-122,65]],[[64533,63266],[174,-211],[58,79]],[[62426,64571],[194,-183],[314,-13],[-297,-302],[171,-198]],[[63339,67732],[365,-176],[-172,-286],[77,-40],[-185,-201],[-252,-124],[298,-182],[200,16],[194,-147],[52,-252],[-269,-386],[87,-199],[-243,-331],[-406,-317],[-92,141],[-119,-87],[-112,-265],[-336,-325]],[[67578,67284],[-390,183],[-433,52],[-402,189],[-75,-52],[-179,219],[-526,452],[-225,70],[-208,205],[-193,-37],[-166,106],[-95,-93],[-470,-50],[-352,-127],[-525,-669]],[[65541,62151],[-439,-370],[-214,-345],[-263,27],[-169,-327]],[[66030,59328],[-165,-249],[174,-146],[81,87],[695,-371],[266,236],[230,322],[304,-198],[240,67],[181,227],[-62,169],[91,106],[-329,227],[265,568],[357,488],[-228,225],[-363,172]],[[61470,57873],[189,358],[277,-107],[72,-310],[169,64]],[[60827,58985],[216,-186],[1,-622],[282,-81],[144,-223]],[[59557,58102],[75,414],[135,229],[-65,144],[329,321],[426,95],[370,-320]],[[58873,58856],[68,-380],[158,-183]],[[61662,62593],[-24,227],[-416,21],[-365,213],[-252,265],[-265,-554],[87,-125],[-69,-427],[85,-149],[-235,-64],[-271,-313],[-599,-484],[-307,325],[-212,-50],[-378,33],[-378,-238],[-11,-428],[657,-473],[-104,-323],[217,-70],[56,-140],[217,-76],[23,-356],[-136,-225],[164,-179],[-41,-173],[-232,26]],[[56500,66474],[-137,311],[-45,-136],[-272,-51],[-443,59],[-344,-264],[-452,-139]],[[55577,64204],[35,85],[248,-6],[283,-199],[22,126],[226,321],[642,269],[43,-58],[280,488],[-227,242],[100,267],[-427,113],[-296,-23],[-146,145],[140,500]],[[54807,66254],[-14,-800]],[[69153,62956],[225,-7],[206,220],[151,317],[142,-57],[171,273],[-3,173],[239,482],[-172,158]],[[60003,57809],[375,224],[215,-36],[168,125],[64,361],[-96,388],[98,114]],[[59363,55877],[423,-180],[156,398],[406,9],[307,-52],[70,253],[175,-32],[2,405],[339,23]],[[61241,56701],[-26,182],[150,437],[-95,78],[200,475]],[[63339,67732],[-426,-117]],[[62913,67615],[-176,-153],[-450,-612],[-492,-560],[-283,-409],[-329,-278],[-182,-504],[50,-359],[586,-355],[271,181],[292,331],[226,-326]],[[60596,53763],[95,491],[355,162],[18,270],[132,152],[132,495],[-121,122],[-7,780],[41,466]],[[59479,54204],[50,6],[612,-428],[455,-19]],[[59044,55655],[-127,-209],[55,-146],[445,-599],[-5,-303],[67,-194]],[[61857,68725],[-341,43],[-125,-93],[-188,115],[-107,-98]],[[62913,67615],[-144,60],[-223,-149],[-507,17],[-237,-91],[-146,195],[-231,109],[-44,175],[166,86],[255,484],[55,224]],[[54658,58473],[302,-142],[156,493],[275,114],[-155,245],[391,338],[83,-67],[112,229],[512,-187],[159,176],[597,-166],[601,-44],[385,-204],[50,-225],[339,-147],[408,-30]],[[56668,67736],[-60,-270],[9,-345],[148,-180],[-265,-467]],[[57807,68794],[-187,-193],[-298,-580],[-298,28],[-139,-156],[9,-316],[-226,159]],[[58095,68266],[-288,528]],[[61096,68692],[-148,-304],[-424,-379],[-75,-153],[47,-323],[-571,-677],[-695,-405],[-139,379],[-180,200],[144,139],[-201,373],[-508,274],[-186,236],[-65,214]],[[10780,25019],[-522,-87],[56,-79],[-262,-53],[-225,-142],[294,-49],[352,-227],[-450,-246],[-386,-381],[-244,121]],[[11581,23849],[207,567],[-129,-3],[-151,236],[-473,-115],[-102,326],[-153,159]],[[9714,22973],[334,250],[159,235],[-60,164],[270,-126],[346,366],[152,-225],[-84,-88],[453,-264],[297,564]],[[9393,23876],[-283,-283],[191,-57],[-146,-211],[320,-157],[239,-195]],[[11147,43752],[-164,302],[-204,121],[-270,-214],[-288,24],[-132,-75],[-248,107],[-427,63],[-163,117],[-256,359],[-426,437],[-486,601]],[[14266,33130],[-76,225],[2,750],[-38,206],[-274,584],[10,365],[-176,263],[-361,133],[-381,-89],[-428,74],[-368,158],[-485,469],[-345,77],[-326,151],[-155,-23],[-263,133],[-212,385],[-310,177],[-61,374],[-314,159],[-83,262],[-464,536],[-278,231],[-249,116],[-384,385],[-319,203],[-311,393],[475,329],[746,600],[347,345],[55,-39],[894,993],[423,637],[411,672],[179,388]],[[14229,32813],[37,317]],[[11410,32214],[-39,34],[496,281],[393,660],[34,-98],[465,148],[459,15],[49,-261],[-96,-259],[30,-168],[160,-64],[410,33],[458,278]],[[9950,33434],[186,-116],[290,-432],[-13,-322],[267,-520],[619,106],[111,64]],[[2922,37682],[82,-186],[49,-488],[149,-285],[689,-271],[500,-97],[185,-523],[-13,-376],[-130,-92],[186,-87],[213,76],[108,-143],[489,-116],[366,172],[215,-30],[289,165],[1148,-418],[592,-3],[-38,-225],[199,-104],[59,77],[179,-216],[384,172],[432,-291],[148,-50],[348,37],[298,-287],[-278,-282],[-303,-46],[-175,51],[37,-207],[184,58],[232,-48],[205,-185]],[[8083,45594],[-691,-730],[406,-328],[-842,-1118],[-475,415],[-1429,-1667],[-749,-975],[-232,-674],[-554,-1239],[-413,-1196],[-182,-400]],[[15614,34921],[-514,455],[-79,307],[-194,330],[-135,97],[-109,277],[-409,157],[-460,356],[27,261],[-232,-8],[-210,87],[-597,776],[-532,752],[-66,-37],[-397,525],[247,472]],[[14652,32823],[17,329],[665,547],[23,532],[191,294],[66,396]],[[14266,33130],[110,-218],[276,-89]],[[12565,42799],[-208,29],[-97,189],[-406,221],[-707,514]],[[15637,34955],[-23,-34]],[[17062,34527],[-225,-101],[-118,275],[-337,-19],[35,153],[-610,-39],[-170,159]],[[17270,32224],[-236,402],[-107,296],[-68,392],[83,-83],[124,146],[-117,219],[257,269],[57,265],[-201,397]],[[15963,31538],[266,132],[378,308],[483,217],[180,29]],[[14652,32823],[128,-74],[278,-376],[174,-511],[-15,-172],[225,-182],[64,-160],[457,190]],[[10030,20626],[167,125],[564,-403]],[[8770,20773],[202,370],[180,-115],[140,295],[738,-697]],[[7851,21371],[115,-49],[-84,-159],[438,-327],[180,214],[98,-210],[172,-67]],[[8846,23176],[-727,-759],[-190,-324],[-158,-565],[80,-157]],[[9217,22707],[-389,305],[18,164]],[[10761,20348],[158,610],[-291,3],[-220,194],[-215,-70],[-496,413],[-611,244],[-157,472],[438,199],[-185,219],[35,75]],[[10780,25019],[-381,448],[199,174]],[[8838,25705],[-206,-267],[470,-556],[120,-214],[-214,-64],[515,-590],[-130,-138]],[[9398,25978],[-143,177],[-163,-259],[-254,-191]],[[10467,25803],[-292,-269],[-211,197],[-67,-67],[-188,163],[-104,-106],[-207,257]],[[10598,25641],[-131,162]],[[8535,20306],[235,467]],[[8135,19301],[342,422],[-134,144],[192,439]],[[6185,19318],[513,-407],[329,330],[122,-173],[415,-294],[222,339],[137,-103],[212,291]],[[7851,21371],[-62,-184],[-488,-428],[-85,-265],[-149,-211],[-746,-287],[-153,-98],[-145,-478],[162,-102]],[[6668,17069],[206,545],[-604,505],[-255,-339],[-241,221],[-241,86]],[[6480,16340],[27,499],[88,285],[73,-55]],[[6263,15634],[44,402],[173,304]],[[5533,18087],[-15,-110],[-393,-346],[-146,-238],[114,-293],[-62,-95],[239,-118],[-54,-118],[458,-487],[81,-204],[508,-444]],[[8692,25847],[146,-142]],[[3006,30632],[1156,-77],[645,-518],[840,-846],[130,-611],[1194,-974],[93,-307],[137,-158],[208,282],[144,-171],[246,184],[30,-175],[178,-220],[-84,-64],[194,-212],[58,73],[720,-811],[-203,-180]],[[10081,27711],[-392,145],[-551,142],[-200,-127],[-361,471],[-127,366],[21,190],[-111,149],[-217,625],[-264,333],[-258,-20],[-309,65],[-395,250],[-348,369],[-320,142],[-272,-39],[-123,-107],[-242,208],[-217,-154],[-157,124],[-471,166],[-487,288],[-121,-61],[-189,276],[-416,348],[-286,-515],[-262,-713]],[[9398,25978],[252,205],[244,329],[443,494],[-222,221],[238,212],[-272,272]],[[15761,29255],[-58,246],[115,25],[-8,594],[-216,135],[48,287],[-252,352],[-192,149],[-177,409]],[[15370,29274],[160,71],[231,-90]],[[13490,30022],[-9,-452],[67,-180],[350,165],[254,-159],[294,-53],[518,183],[229,-44],[177,-208]],[[15021,31452],[-327,131],[37,-350],[-262,-128],[-192,-193],[-77,153],[-690,-296],[25,-457],[91,-226],[-136,-64]],[[6185,19318],[-21,-235],[-231,-107],[66,-143],[-156,-189],[73,-116],[-189,-54],[-194,-387]],[[9526,18526],[-378,379],[-303,-320],[-102,196],[-608,520]],[[9595,16620],[295,392],[110,418],[157,116],[-355,205],[256,182],[-591,413],[59,180]],[[6668,17069],[682,-354],[561,63],[59,-113],[423,-213],[94,136],[293,-37],[132,-110],[79,241],[522,-192],[82,130]],[[9595,16620],[352,-200],[112,-151],[2187,-1223]],[[13282,17058],[-1961,996],[-451,199],[-1233,458],[-111,-185]],[[12246,15046],[686,1287],[350,725]],[[15845,22355],[-2199,804],[-419,469],[-275,206],[-348,150]],[[9714,22973],[319,-236],[222,-269],[180,-36],[533,45],[243,-66],[-15,-206],[164,-379],[176,-109],[464,21],[429,-236],[2411,-1225],[1005,2078]],[[12604,23984],[-523,116],[-70,-462],[-430,211]],[[9217,22707],[497,266]],[[7873,24834],[203,-72],[45,-473],[396,-377],[316,-518],[13,-218]],[[8692,25847],[-195,-60],[-208,211],[-137,-28],[-10,-222],[-123,-451],[-146,-182],[0,-281]],[[12589,29596],[61,-138],[419,-117],[-217,-330],[252,-30],[-147,-152],[173,-169],[-516,-505]],[[13466,30038],[-734,-396],[-143,-46]],[[13490,30022],[-24,16]],[[14524,26919],[223,330],[-88,53],[157,240],[-107,89],[189,208],[199,462],[129,94],[-122,280],[346,103],[-187,314],[107,182]],[[12614,28155],[280,-387],[-125,-163],[264,-87],[364,38],[273,-346],[158,-107],[215,284],[481,-468]],[[12582,25778],[-113,-149],[-308,384],[-182,145],[-170,-464],[-455,272],[-462,-653],[-294,328]],[[12604,23984],[96,209],[-131,300],[385,231],[335,-10],[52,87],[-337,27],[-348,-108],[-152,15],[-16,234],[139,356],[247,207],[-292,246]],[[10030,20626],[-236,-266],[-400,220],[-197,194],[-199,-306],[19,-382],[-152,-48],[-330,268]],[[13282,17058],[763,1577],[-2210,1124],[-201,-37],[-873,626]],[[11410,32214],[177,-140],[197,-348],[-95,-99],[288,-342],[186,145],[304,-257],[-69,-268],[475,-254],[250,1],[250,-353],[93,-261]],[[15021,31452],[21,381],[-264,605],[-269,241],[-280,134]],[[1742,32477],[-805,-902]],[[9821,30148],[-291,93],[-281,219],[-211,49],[-219,-62],[-413,368],[-769,456],[-295,92],[-252,249],[-505,310],[-596,15],[-267,226],[-1292,275],[-93,-74],[-588,615],[-341,253],[-273,46],[-218,173],[-334,-270],[-182,-37],[-278,-229],[-75,-336],[-306,-102]],[[11194,28369],[-457,424],[-211,295],[-509,922],[-196,138]],[[10081,27711],[365,123],[349,-24],[74,235],[325,324]],[[937,31575],[188,-145],[548,-304],[64,-90],[329,146],[264,278],[516,-374],[-157,-279],[317,-175]],[[9950,33434],[-51,-131],[-285,-221],[-212,-25],[-411,87],[-138,97],[-181,-297],[565,-189],[201,-154],[198,-451]],[[9636,32150],[270,-376],[135,-33],[458,-570],[452,-236],[352,-29],[301,-196],[276,-288],[201,-390],[292,-319],[216,-117]],[[19259,24937],[2765,2091]],[[16150,28987],[303,-91],[425,-337],[214,-331],[-11,-114],[439,-217],[-119,-161],[190,-150],[-18,-212],[431,-694],[1255,-1743]],[[15963,31538],[187,-388],[184,-229],[-140,-131],[85,-150],[-98,-587],[44,-456],[123,19],[93,-417],[-291,-212]],[[18159,30961],[-272,127],[-171,168],[60,145],[-392,781],[-114,42]],[[22024,27028],[-2356,3273],[-185,138],[39,188],[-227,94],[-53,221],[-241,76],[-435,-255],[-407,198]],[[12011,27560],[-75,181]],[[10467,25803],[532,442],[158,300],[479,763],[78,-66],[297,318]],[[11936,27741],[-109,333],[-261,-137],[-372,432]],[[11841,14284],[-2435,1364],[-392,100],[-31,187],[-141,139],[-314,-141],[-243,48],[-534,351],[-289,-4],[-409,-114],[-479,270],[-94,-144]],[[6263,15634],[-5,-85],[828,-483],[229,-232],[523,-188],[636,-329],[263,-55],[2383,-1332],[721,1354]],[[12011,27560],[463,-14],[188,-152],[-278,-457],[-78,-251],[204,-235],[386,-231],[-314,-442]],[[12614,28155],[-306,-151],[51,-141],[-423,-122]],[[17135,23331],[-1687,2343],[-560,373],[-2,177],[-223,96],[64,194],[-112,45],[-91,360]],[[15845,22355],[1290,976]],[[17135,23331],[2124,1606]],[[16150,28987],[54,187],[-252,-6],[-191,87]],[[937,31575],[-65,-475],[-285,-351],[-587,-1131],[312,-191],[1247,-365],[1274,-413],[150,-231],[48,-310],[461,-673],[266,11],[415,-347],[71,91],[-135,299],[1560,-1271],[249,-165],[1171,-1292],[70,-127],[356,-2],[77,133],[189,-116],[92,185]],[[9821,30148],[-39,493],[-367,435],[-395,14],[298,378],[318,682]],[[2922,37682],[-972,-941],[-745,-770],[-347,-235],[90,-248],[-47,-448],[287,-291],[-219,-507],[346,-400],[482,-373],[162,-448],[-72,-380],[-145,-164]],[[11841,14284],[405,762]],[[15637,34955],[83,221],[2,429],[-100,225],[-6,420],[137,386],[-10,328]],[[36566,69971],[41,251],[151,294],[157,147],[-137,211],[478,1004]],[[35370,70264],[316,70],[388,-37],[-14,-177],[350,-50],[-62,-113],[218,14]],[[32193,72964],[598,-716],[549,-21],[890,-574],[439,-560],[264,-184],[-66,-106],[373,-304],[-117,-293],[247,58]],[[33304,73839],[-283,-115],[-828,-760]],[[33477,73007],[-131,351],[-42,481]],[[37256,71878],[-514,260],[-62,117],[-921,447],[-245,-257],[-432,-248],[-367,434],[-146,292],[-383,-203],[-394,-106],[-203,-124],[-203,-7],[-108,191],[199,333]],[[36256,66651],[391,-72],[-142,-128],[-32,-209],[670,-145],[-29,-237],[339,-118],[97,-129],[353,42],[265,-106],[-39,-608],[100,54]],[[36329,68043],[-340,-813],[289,-421],[-22,-158]],[[36748,68089],[-419,-46]],[[39039,67988],[-493,-246],[-149,102],[-386,67],[-391,-140],[-216,123],[-197,-53],[-201,59],[-258,189]],[[39292,65240],[72,195],[-350,87],[182,586],[83,602],[-46,292],[115,199],[46,613],[-284,-42],[54,197],[-125,19]],[[38229,64995],[172,104],[247,4],[53,263],[591,-126]],[[37105,62688],[-36,-376],[135,-82],[-122,-606],[-299,236],[-451,-182],[-177,-597]],[[38229,64995],[-296,-618],[-400,-203],[8,-222],[-294,-130],[32,-182],[168,-59],[-30,-174],[-178,-247],[-134,-472]],[[40482,64161],[-287,63],[2,199],[-291,95],[-83,160],[-531,562]],[[41269,63951],[-787,210]],[[41298,63136],[-29,815]],[[31871,68188],[-72,407],[-121,323],[-294,544],[-620,293],[-135,174],[-115,511],[-142,308],[-46,443]],[[31335,67561],[355,363],[181,264]],[[27607,68620],[444,-189],[132,-188],[74,-267],[345,-544],[140,-36],[393,69],[119,-65],[223,-441],[579,92],[215,194],[192,70],[149,-94],[157,189],[113,-12],[319,171],[134,-8]],[[30326,71191],[-1155,-321],[-208,111],[-85,-152],[-396,-144],[-578,-639],[147,-133],[150,-412],[-223,-484],[-371,-397]],[[31884,77268],[1959,-1615],[-581,-1261],[42,-553]],[[41579,76049],[-46,199],[-247,227],[-112,-56],[-78,289],[-315,226],[-95,211],[-776,263],[-181,398],[24,66]],[[40170,73877],[199,406],[228,148],[97,-80],[307,340],[78,241],[157,-85],[290,366],[-102,93],[177,252],[-82,12],[177,338],[-117,141]],[[33477,73007],[96,6],[288,505],[-34,141],[415,-124],[514,421],[136,-161],[303,284],[343,-140],[347,-55],[618,-179],[584,-258],[336,-216],[741,-295],[364,511],[266,-182],[163,242],[502,-318],[-86,298],[342,366],[176,-117],[279,141]],[[44306,62120],[-136,89],[-140,337],[-12,512],[-190,58],[-183,356],[-379,355],[-302,379],[-102,-214],[-345,159],[-17,-61],[-1039,302],[-192,-441]],[[35796,64232],[253,105],[146,-97],[412,-74],[-164,-423],[453,-68],[67,-566],[110,-78],[-113,-290],[145,-53]],[[35424,64916],[265,-147],[166,-276],[-59,-261]],[[36256,66651],[-102,-299],[-238,-60],[-169,-309],[39,-256],[-136,-407],[-188,-33],[-133,202],[95,-573]],[[33144,67700],[-149,-218],[19,-551],[184,-223],[324,32],[-17,-417],[154,-10],[11,-258],[370,29],[30,-153],[-71,-350],[-82,-88],[178,-240],[181,-534]],[[36329,68043],[-115,-37],[-208,-264],[-539,9],[-511,185],[-95,-228],[114,-134],[26,-256],[-181,249],[-457,216],[-264,14],[-475,-138],[-480,41]],[[34276,64719],[116,-41],[275,133],[-21,95],[263,-133],[515,143]],[[43757,69682],[-334,-311],[-460,-918],[-55,47],[-211,-383],[196,-42],[-323,-444],[-658,-1045],[-203,68],[-182,178],[-124,-253],[-648,-610],[-110,-253],[-163,-1555]],[[45126,68958],[-194,-94],[-256,145],[-919,673]],[[47146,65169],[-167,-225],[-450,-82],[-223,97],[-139,519],[175,357],[-103,137],[-282,-99],[35,162],[-391,196],[-102,-81],[-108,122],[-243,-223],[-157,80],[-218,283],[-490,421],[256,227],[-155,370],[-6,263],[444,563],[304,702]],[[37446,69707],[-212,513],[-262,-60],[-76,-111],[-330,-78]],[[36748,68089],[191,558],[64,-14],[575,757],[-132,317]],[[31932,67228],[527,624],[685,-152]],[[31335,67561],[450,-487],[147,154]],[[35370,70264],[-105,-888],[-138,-379],[-254,-235],[-188,-29],[-484,380],[-327,78],[-66,-136],[-962,112],[-157,-123],[-252,-629],[-277,-65],[-289,-162]],[[35796,64232],[-939,-404],[-165,-229],[87,-72],[280,109],[121,-382],[-116,-263],[-23,-261],[-195,-235],[78,-400],[219,-392],[351,-181],[360,-273]],[[34527,60746],[489,470],[-357,49],[-563,169],[-84,-221],[99,-292]],[[28548,61142],[1489,865],[691,184],[254,-138],[461,-338],[643,-260],[262,-417],[-188,-258],[242,-42],[-203,-307],[157,-130],[-108,-141],[41,-251],[106,-109]],[[30994,64112],[-23,-342],[-318,13],[-491,-349],[-617,-62],[-120,80],[-59,-211],[-432,117],[-425,-631],[-76,-275],[137,-98],[-385,-491],[90,-46],[-219,-296],[-107,-498]],[[32644,59823],[-36,351],[181,705],[801,849],[15,-205],[275,-184],[192,465],[-224,159],[56,213],[-150,2],[-169,-243],[37,237],[380,65],[85,282],[-229,101],[-119,174],[-117,-300],[-81,297],[-131,203],[-3,431],[127,69],[-335,197],[-26,124],[-451,8],[-227,111],[-195,-135],[-123,134],[-161,-149],[-211,-63],[-258,260],[-224,-94],[-329,225]],[[32193,72964],[-58,-52],[-50,-443],[122,-48],[-768,-735],[-481,-285],[-632,-210]],[[37530,69753],[-84,-46]],[[39553,69286],[-364,13],[74,210],[-285,250],[-281,-140],[-325,-4],[-70,114],[-378,176],[-111,-217],[-283,65]],[[39039,67988],[-66,179],[115,454],[141,278],[181,-14],[143,401]],[[43899,70103],[-1232,-847],[-318,531],[-283,388],[-696,-472],[-180,277],[-338,265],[-438,201],[-248,-170],[-121,-264],[-433,-71],[32,-328],[-91,-327]],[[44121,69934],[-222,169]],[[43757,69682],[364,252]],[[31932,67228],[242,-297],[-703,-869],[-687,-269],[-447,-107],[-177,-134],[-672,-237],[-263,-169]],[[31435,64317],[224,178],[313,62],[116,159],[578,-198],[67,63],[652,-115],[534,295],[357,-42]],[[29225,65146],[187,-145],[436,110],[31,-73],[219,224],[309,165],[368,-657],[302,149],[187,-458],[171,-144]],[[41200,72801],[-108,475],[-168,270],[-30,219],[-485,8],[-239,104]],[[41014,71694],[490,525],[-247,200],[-112,181],[55,201]],[[37970,71429],[702,337],[339,-64],[200,-287],[431,91],[165,153],[31,-282],[187,53],[79,-125],[310,-128],[498,374],[102,143]],[[37256,71878],[182,213],[278,14],[22,-323],[232,-353]],[[31435,64317],[-389,-72],[-52,-133]],[[37530,69753],[285,810],[76,544],[-49,117],[266,75],[-138,130]],[[43899,70103],[-1746,931],[-415,-395],[-190,170],[-147,-176],[-378,317],[92,115],[-177,199],[230,225],[-154,205]],[[24627,62678],[245,106],[54,117],[459,337],[287,309],[-36,171],[436,374],[303,140],[414,33],[325,-91],[175,94],[130,423],[428,-212],[189,-161],[250,196],[457,241],[482,391]],[[23487,62854],[381,-24],[759,-152]],[[21023,64593],[48,-86],[1728,-1101],[688,-552]],[[27607,68620],[-14,-60],[-491,-114],[-340,95],[-329,-57],[-296,-183],[310,1],[25,-633],[-420,-110],[-168,-172],[-294,68],[-87,98],[-246,-417],[-299,-186],[-141,-416],[-234,-49],[-690,-530],[-1189,-468],[-169,32],[-808,-469],[-704,-457]],[[24627,62678],[-56,-154],[28,-596],[-83,-577],[50,-564]],[[42700,78746],[-61,141],[-407,516]],[[43301,77380],[130,182],[-98,376],[-202,295],[-203,124],[-228,389]],[[41579,76049],[108,55],[233,-105],[287,118],[359,415],[-5,-258],[302,37],[-107,130],[299,68],[74,-102],[315,-108],[26,181],[-127,197],[5,204],[-215,309],[168,190]],[[57422,50444],[107,-10]],[[56853,49929],[67,374],[244,420],[258,-279]],[[54688,51082],[384,-6],[-73,-224],[204,-341],[-47,-391],[285,-224],[409,-94],[-11,-331],[201,22],[223,272],[195,-91],[395,255]],[[57117,54760],[-145,-342],[-178,-269],[-168,-108],[-58,-175],[-298,-455],[-251,25],[-231,-412],[-440,-156],[-308,-533],[71,-342],[-96,-431],[-236,82]],[[57529,50434],[81,210],[4,572],[-76,138],[-32,552],[101,385],[275,575],[-259,110],[105,95],[44,298],[-215,162],[85,342],[491,891]],[[67956,44404],[79,220],[415,282],[121,241],[213,125],[114,261],[462,503],[339,451],[257,-87],[-26,103],[254,72],[208,181],[166,-112],[272,216],[-218,263],[-38,403],[210,376],[-308,111],[-220,-177],[-415,-208],[-192,29],[-147,-334],[-10,-273],[-157,-109],[-422,650],[-420,-267],[-227,587]],[[68266,47911],[-48,-208],[-252,-46],[-173,-226],[-169,-71],[145,-235],[117,87],[119,-177],[-154,-60],[-290,-279],[-65,-177],[203,-454],[-233,-556],[30,-69],[300,221],[-54,-193],[39,-468],[148,-380],[27,-216]],[[57422,50444],[-320,-159],[-249,-356]],[[58026,50703],[-497,-269]],[[57944,49295],[116,233],[-30,234],[98,482],[-71,107],[-31,352]],[[57424,48504],[144,151],[21,249],[213,144],[142,247]],[[58026,50703],[8,184],[263,449],[528,384],[58,417],[-54,190],[150,178],[-40,191],[135,313],[190,262],[107,557],[-46,123],[154,253]],[[62183,49696],[-312,-8],[-19,-364],[-234,18],[-54,201],[-324,178],[-144,7],[-67,162],[-491,-67],[-175,150],[-185,12],[-121,-308],[112,-340],[-29,-338],[-492,-425],[-124,343],[-262,172],[-232,-24],[-512,178],[-147,-152],[-427,204]],[[61802,48684],[126,232],[-8,258],[238,336],[25,186]],[[60198,46958],[639,640],[290,-23],[183,347],[194,65],[121,390],[177,307]],[[62125,51737],[305,106],[172,1081],[-166,771],[96,93],[-43,309],[89,449],[-122,339],[29,334],[-136,87],[-18,185],[-172,32],[-119,374],[109,312],[67,494],[237,574],[125,-56],[41,238],[-255,114],[-153,157],[15,170]],[[60596,53763],[-28,-129],[287,-68],[101,-518],[-94,-390],[-126,-140],[394,-131],[140,35],[-17,-409],[-72,-132],[312,-178],[279,-73],[353,107]],[[68266,47911],[-316,690],[-237,136],[41,128],[-231,117],[-236,213],[-207,31],[-409,238],[-100,-113],[-179,116],[-80,183],[-158,64],[-84,-138],[-258,-48],[-219,-433],[-243,-178],[43,-86],[-222,-186],[-468,133],[-202,201],[-264,-59],[-131,326],[-94,407],[-575,298],[-220,-626],[139,-303],[-321,80],[-124,-154],[-256,42],[-130,-131],[-69,-244],[-260,-104],[-394,173]],[[63226,42492],[42,129],[390,607],[79,562],[258,196],[-12,138],[311,311],[123,249],[132,-87],[-260,-440],[34,-170],[930,-43],[692,148],[542,265],[348,38],[13,-182],[137,-228],[-15,-164],[280,-99],[-128,-338],[28,-298],[261,34],[46,486],[109,-27],[59,395],[205,335],[126,95]],[[62183,49696],[24,255],[-81,58],[122,330],[0,244],[114,231],[-86,140],[-151,783]],[[60447,71435],[-45,-165],[-289,-297],[41,-280]],[[60948,72654],[-280,-392],[-41,-266],[-125,-27],[40,-207],[-95,-327]],[[61500,73141],[-87,60],[-465,-547]],[[62228,71988],[34,391],[-116,99],[190,154],[-94,179],[-232,-186],[-510,516]],[[61261,70214],[91,230],[145,59],[331,330],[366,515],[-20,155],[-175,7],[-43,183],[272,295]],[[60154,70693],[257,-249],[230,217],[338,-298],[282,-149]],[[71810,86761],[577,414],[89,229],[238,204],[-8,230],[291,242],[87,178]],[[73084,88258],[-112,99],[-52,254],[426,301],[110,195],[-295,199],[-444,567],[-2088,2504],[-2565,-1970],[2155,-2872],[244,-218],[146,-246],[75,112],[314,-228],[214,-340],[140,113],[135,-215],[323,248]],[[75729,79072],[219,526],[367,584],[242,-155],[148,-283],[172,-105],[91,94],[154,-208],[274,5],[576,-135],[35,186],[362,360],[0,219],[227,279],[1,346],[-520,197],[73,307],[-326,333],[109,151],[136,-122],[207,250],[18,176],[-353,405],[-246,-124],[-182,157],[97,158],[-212,219],[-27,160],[149,252],[-125,212],[234,381],[-303,316],[193,634],[80,86]],[[75098,84363],[56,-496],[372,-862],[-342,-322],[-323,-750],[-360,-706],[174,-287],[277,-288],[197,-315],[-311,-386],[172,-67],[225,-366],[338,-171],[-83,-184],[239,-91]],[[76321,84827],[-154,-98],[-77,126],[-992,-492]],[[76703,85068],[-382,-241]],[[77599,84933],[-40,51],[-276,-184],[-296,448],[-284,-180]],[[71810,86761],[846,-1168],[-434,-223],[59,-93],[-402,-201],[-178,294],[-389,-132],[-354,-253],[-191,85],[-160,-141],[-393,-116],[185,-237],[148,-41],[48,-190],[1376,578],[233,-363],[175,18],[178,-346],[130,40],[72,-213],[151,49],[246,-617],[143,49],[90,-131]],[[76321,84827],[-385,759],[-195,-82],[-327,579],[-153,-93],[-135,140],[161,60],[-59,173],[-259,170],[-237,511],[-272,88],[-82,294],[-198,137],[-58,350],[-198,-146],[-237,471],[-322,101],[-281,-81]],[[73389,83409],[467,412],[402,287],[350,15],[490,240]],[[70227,70596],[-102,-104],[-313,209],[60,67],[-235,154],[-341,-498]],[[70516,68903],[246,447],[42,197],[-392,116],[179,388],[-124,259],[-240,286]],[[67975,68315],[399,-296],[900,1309],[161,-151],[343,98],[85,-368],[381,-191],[272,187]],[[69296,70424],[-1350,-2088],[29,-21]],[[77599,84933],[532,552],[-44,40],[248,298],[-686,1050],[-239,301],[-113,-18],[-218,407],[-285,-104],[59,-171],[-394,-211],[-255,-72],[-99,161],[-130,-200],[-208,-128],[130,-288],[-53,-56],[258,-178],[229,-447],[-47,-67],[419,-734]],[[74068,74355],[52,-85],[208,337],[327,123],[155,-190],[213,-33],[121,303],[431,260],[76,123],[-92,279],[40,254],[-76,109],[587,782],[253,172],[61,200],[-267,230],[103,115],[-288,326],[-285,397],[126,126],[-230,341],[312,351],[-166,197]],[[72222,75061],[160,-22],[-39,-549],[296,-144],[50,107],[410,192],[207,33],[160,239],[262,159],[230,-158],[-22,-204],[125,-135],[7,-224]],[[73389,83409],[57,-83],[-859,-640],[-864,-1158],[32,-25],[-268,-544],[-41,-703],[-178,-431],[230,-654],[137,-121],[-147,-161],[170,-27],[-94,-133],[194,-481],[-505,-861],[539,-314],[376,438],[-84,95],[438,392],[206,-236],[415,43],[83,-215],[184,-108],[77,-212],[-76,-204],[-294,-244],[-148,-368],[-345,-151],[-33,-236],[-241,-592],[-118,-158],[-10,-256]],[[71743,74145],[-259,-531],[309,-171],[-86,-402],[417,-224],[-170,-199],[258,-279],[-195,-318]],[[72222,75061],[41,-284],[-129,-191],[-284,-225],[-107,-216]],[[72017,72021],[309,-127],[-88,-74],[253,-161],[241,267],[698,952],[344,242],[-340,114],[155,272],[-126,79],[469,410],[136,360]],[[62228,71988],[63,-40],[584,584],[527,615],[-23,157],[408,419],[208,80],[-5,147]],[[62275,74614],[-341,-324],[81,-80],[-219,-188],[-56,-264],[-232,-298],[83,-89],[-91,-230]],[[63990,73950],[-351,119],[-104,-34],[36,242],[-350,436],[-381,242],[-302,-224],[-101,92],[-162,-209]],[[71684,70840],[-48,-204],[-248,143],[-165,-37],[-291,75],[-200,230],[-357,-222],[-148,-229]],[[72508,66882],[124,237],[697,823],[438,378],[86,148],[-132,187],[114,310],[269,401],[135,441],[-129,73],[-131,470],[-249,133],[-398,466],[-498,-246],[-358,-114],[-202,376],[-238,-127],[-245,167],[-107,-165]],[[70516,68903],[146,-179],[290,48],[61,-193],[242,-135],[229,-269],[55,-368],[200,45],[272,410],[31,-304],[281,-108],[170,-295],[178,-67],[-163,-606]],[[61261,70214],[-114,-226],[-75,-871],[32,-149],[-102,-209],[94,-67]],[[71743,74145],[-229,290],[147,145],[-221,81],[-193,-283],[-131,48],[-366,-38],[58,-192],[-404,-117],[-70,-225],[-508,125],[-721,-366],[1,130],[-194,-51],[-384,355],[-69,-74],[-206,187],[-374,120],[-247,328],[169,153],[-399,453],[-548,-338],[-81,77],[-201,-227],[130,-111],[-192,-281],[-111,40],[-111,-173],[-225,-138],[-294,282],[-284,-605],[-274,-192],[-418,264],[-208,-462],[-326,424],[-269,176]],[[71684,70840],[-130,189],[140,157],[-200,149],[283,475],[240,211]],[[61857,68725],[124,-96],[139,169],[121,-287],[264,133],[233,214],[161,-185],[473,279],[224,-37],[182,138],[-105,268],[130,74],[390,440],[82,292],[409,401],[-51,234],[177,-51],[163,256],[-189,76],[94,199],[196,131],[423,485],[336,198],[408,398],[-156,89],[196,182],[245,385],[-227,27],[131,451],[-1,-215],[232,-13],[174,136],[-59,-258],[221,-19],[144,-176],[86,-360],[247,-171],[-51,-328],[-162,-126],[96,-162],[144,175],[242,81],[164,-122],[351,-508],[408,-155],[208,-180],[-106,-247],[362,-262],[166,-254]],[[70602,65244],[249,369],[233,247],[298,202],[343,358],[328,85],[101,178],[104,-166],[250,365]],[[67975,68315],[-85,-147],[111,-101],[-122,-192],[210,-115],[-288,-400],[-151,74],[-72,-150]],[[93359,43095],[-265,-142],[-311,-317],[-424,-213],[-210,76],[-254,-12],[-381,145],[-282,-199],[-115,-594],[-559,-1124],[-71,-561],[-448,-493],[-390,-186],[17,-48],[-318,-508],[-394,-145],[-714,-395],[-253,-263],[-44,-249],[-268,-295],[-222,-109]],[[95403,31636],[111,355],[-49,282],[161,315],[-36,286],[77,231],[185,203],[-427,249],[-858,921],[185,138],[-72,352],[-271,550],[-281,724],[249,174],[-179,524],[203,596],[157,111],[34,364],[-91,246],[42,159],[-153,219],[-449,378],[-203,21],[-71,138],[-339,135],[-108,171],[1,437],[75,249],[-359,436],[501,582],[381,766],[-168,130],[-163,261],[-129,756]],[[95275,23947],[106,725],[302,568],[-9,149],[209,276],[90,326],[155,217],[68,400],[275,320],[-69,676],[129,683],[121,303],[-260,378],[-35,244],[-231,103],[-270,489],[-103,412],[-533,564],[-22,183],[205,673]],[[87453,37463],[45,-119],[350,-338],[3,-328],[194,-744],[-277,19],[102,-249],[-198,-550],[-218,-185],[74,-140],[-267,-158],[20,-128],[-199,-201],[-285,-432],[-378,-207],[-111,44],[-474,-218],[-124,-195],[-573,-277],[-23,-104],[-254,-172],[-358,-93],[-44,-206],[-144,-154],[-317,-153],[-409,-49],[-647,-536],[-290,155],[-53,105],[-519,102],[-176,-240],[-349,-338],[-205,-93],[-297,382]],[[80465,32535],[23,-146],[341,-47],[44,-312]],[[87453,37463],[-197,179],[-768,-181],[-164,108],[-381,0],[-408,134],[-438,-302],[-199,74],[-353,259],[-400,-219],[-170,-256],[-394,-307],[-296,-114],[-269,-355],[-312,-297],[-468,-281],[-853,-933],[-143,-330],[-162,-104],[-392,-484],[80,-107],[-121,-753],[-180,-659]],[[95403,31636],[320,-58],[283,77],[180,-196],[750,34],[483,232],[313,78],[218,283],[160,650],[-88,272],[317,214],[219,70],[-491,452],[203,172],[79,335],[-77,92],[167,523],[-298,738],[-194,633],[-31,919],[-37,257],[289,-68],[-6,107],[733,101],[-14,413],[-138,343],[-143,102],[390,88],[350,195],[85,291],[238,335],[-61,61],[43,332],[130,107],[-13,294],[160,251],[36,281],[-113,179],[154,863],[-96,120],[-9,435],[-110,454],[-29,350],[-127,149],[110,543],[-115,306],[-158,143],[-314,534],[-157,122],[-4,930],[-53,36],[-386,-373],[-49,32],[-501,-273],[-236,-272],[-72,-271],[-130,-106],[-457,-681],[-408,-541],[-191,-155],[-551,888],[-22,212],[-620,557],[-104,53],[-129,-209],[-281,-285],[-422,-526],[-128,-45],[-673,-582],[-218,-138]],[[26581,35465],[135,-245],[1161,-6635]],[[27877,28585],[2632,484]],[[21510,32911],[-207,252],[-189,-187],[-183,180],[-314,-179],[-165,243],[-584,-356]],[[24423,27950],[-2743,4753],[-170,208]],[[22861,27663],[1562,287]],[[19874,31949],[276,-149],[305,-327],[-45,-49],[314,-156],[2137,-3605]],[[19868,32864],[196,-461],[-191,-306],[1,-148]],[[17557,34794],[491,-640],[39,-230],[160,-175],[572,-911],[-109,-93],[146,-333],[-61,-108]],[[18245,36001],[-291,-78],[-128,-236],[115,-372],[-181,-360],[-203,-161]],[[19868,32864],[-313,598],[-64,204],[-176,178],[30,144],[-196,298],[-244,527],[-431,549],[-229,639]],[[19131,32026],[209,23],[156,-323],[174,22],[204,201]],[[18795,32304],[336,-278]],[[18576,37138],[-254,378],[43,302]],[[18245,36001],[218,10],[183,141],[12,188],[-127,247],[45,551]],[[17256,34661],[301,133]],[[17062,34527],[194,134]],[[19131,32026],[-264,-435],[76,-266],[-272,-108],[-185,196],[-327,-452]],[[22024,27028],[837,635]],[[20319,37119],[291,35],[59,-290],[134,-162],[241,-119],[152,-310],[125,-538],[191,-378],[286,-216],[244,-23]],[[18576,37138],[251,153],[642,-100],[331,99],[13,-80],[506,-91]],[[22042,35118],[121,252],[192,178],[-138,351],[31,201],[-154,469],[-41,327],[52,290],[185,136],[-97,244],[339,53],[-100,205],[276,128],[-154,335],[130,178],[237,-127],[135,175]],[[21608,34821],[-61,120],[-306,248],[-414,85],[-188,481],[147,119],[-269,406],[-152,146],[40,158],[-132,330],[46,205]],[[21510,32911],[546,462],[-184,240],[172,130],[-378,441],[254,268],[-312,369]],[[18795,32304],[-487,463],[-54,-57],[-217,267],[-443,648],[-137,388],[41,139],[-242,509]],[[24364,35085],[-94,525],[-160,269],[-215,126],[-85,370],[31,246],[-262,567],[67,75],[333,-50]],[[22060,35114],[522,290],[598,277],[17,-508],[314,111],[76,-183],[360,170],[48,-233],[369,47]],[[22042,35118],[18,-4]],[[25512,28150],[2365,435]],[[24364,35085],[-16,-279],[1164,-6656]],[[22060,35114],[-254,-227],[-198,-66]],[[24423,27950],[1089,200]],[[17062,55490],[-911,-965],[555,-682],[1110,-1425],[25,-422],[603,-528],[469,-283],[436,-440],[-63,415],[105,85],[155,-411],[375,-299],[198,-50]],[[23487,62854],[-198,-269],[-417,-368],[61,-148],[-644,-759],[-224,-398],[235,-209],[65,42],[311,-389],[-1639,-1816],[-3045,-2404],[-930,-646]],[[13519,57981],[-201,-243],[64,-105],[-387,-148],[6,-119],[-427,-511],[-203,-116],[-126,163],[-385,-214],[89,-115],[-290,-432],[-62,-183],[-483,-392],[-447,-215],[-182,-283],[-334,-156],[17,-240],[-70,-303],[-620,-394],[-537,-297],[-347,-7],[-283,-281],[-361,-498],[-480,-176],[-527,-502],[-189,-55],[-829,-743],[-286,-201],[-223,-307],[-182,-426],[-582,-499],[-390,-430],[1412,-1481],[2409,-2478]],[[17062,55490],[-615,407],[-84,140],[-188,-229],[-326,210],[-228,-6],[-243,-262],[-705,802],[-1154,1429]],[[21023,64593],[-863,-564],[-130,31],[-258,-173],[-569,-212],[-313,-78],[-254,-393],[-266,-224],[-574,-382],[-32,-309],[113,-187],[-186,-54],[-64,-240],[-1196,-1102],[-923,-782],[-363,-409],[-455,-381],[-170,-357],[-277,-419],[-319,-240],[-405,-137]],[[60702,31077],[1224,-365]],[[64925,39862],[-192,927],[-510,-44]],[[65528,36117],[-78,82],[-38,327],[69,199],[190,188],[61,248],[-60,422],[-152,94],[184,324],[-62,326],[-274,331],[-191,639],[-248,371],[-4,194]],[[65493,35979],[35,138]],[[61926,30712],[1361,4777],[-1,304],[156,139],[178,-10],[266,-148],[214,-29],[47,140],[351,105],[5,-123],[242,102],[348,-25],[400,35]],[[63468,30252],[1396,4903],[363,195]],[[61926,30712],[1542,-460]],[[65227,35350],[491,311],[-225,318]],[[67033,36490],[69,135],[207,16],[297,228],[181,-37],[100,331],[202,83],[389,311],[117,350],[329,408],[104,310],[133,60],[259,516],[237,271],[199,132],[106,203],[314,223],[-43,128]],[[65227,35350],[-6,-140],[158,-83],[246,166],[251,15],[181,96],[131,208],[229,89],[532,601],[84,188]],[[67070,38368],[-97,-357],[42,-180],[-194,-101],[-47,-296],[-139,-102],[97,-177],[-212,-53],[-14,-218],[-120,-291],[-514,-231],[-146,-184],[-198,-61]],[[70233,40158],[-59,185],[89,466],[136,248],[-73,688],[-118,-145],[-1153,-830],[-786,-1028],[-250,-254],[-266,-182],[-136,-283],[-171,-582],[-376,-73]],[[67070,38368],[-792,22],[-280,414],[-219,-41],[-427,399],[-427,700]],[[68799,27949],[3699,1353],[437,185],[63,83],[574,146],[429,292],[382,140],[118,102],[236,-68],[334,253],[324,43],[253,196],[286,48],[178,133],[474,111],[392,-104],[79,-94],[285,369],[284,251]],[[69315,33418],[-78,-368],[-202,-234],[-140,-34],[-76,-234],[-175,-148],[-1557,-3693]],[[77130,35795],[-230,-30],[-503,173],[-113,243],[-184,116],[-72,324],[137,421],[-17,312],[-259,103],[-242,-292],[-21,-224],[-438,-217],[-264,-69],[-46,106],[-285,13],[-480,-90],[-331,50],[-759,-231],[-259,-126],[-63,-417],[14,-319],[128,-334],[-113,-325],[-43,-321],[-110,-112],[-452,-3],[-452,-291],[-114,82],[-93,-119],[-287,64],[-150,-68],[-246,66],[-380,-301],[-105,75],[-82,-318],[-226,5],[-207,-175],[-271,90],[-197,-238]],[[77626,31388],[52,319],[299,427],[331,602],[-199,509],[-448,498],[-139,262],[-214,7],[-99,304],[2,669],[-62,90],[62,363],[-81,357]],[[67447,34637],[-117,-174],[127,-87],[-139,-182],[-337,-37],[-190,-252],[-265,-97],[-1724,-4089]],[[69315,33418],[-333,207],[10,206],[-287,445],[-159,405],[-443,-126],[-267,84],[-79,132],[-310,-134]],[[67447,34637],[-221,158],[-350,-95],[-120,343],[-151,184],[130,395],[-122,162],[211,34],[131,160],[188,406],[-110,106]],[[63468,30252],[453,-144]],[[80465,32535],[-43,80],[-426,-168],[-341,-208],[-475,-178],[-290,-236],[-529,-328],[-453,-116],[-282,7]],[[77130,35795],[288,271],[-462,379],[-173,380],[16,160],[-125,350],[91,479],[-153,273],[-114,-48],[-393,256],[-181,387],[-610,410],[-161,303],[-294,89],[-241,-161],[-368,-7],[-133,107],[-114,-101],[-366,-28],[-217,82],[-344,402],[-162,-23],[-201,379],[-279,60],[-528,267],[-235,174],[-114,201],[-112,-111],[-497,109],[-266,5],[35,-111],[-143,-242],[-341,-328]],[[46805,68559],[58,-255],[519,-790],[69,-39],[-60,-307],[9,-380],[-181,-444],[302,-214]],[[46787,71445],[240,-610],[42,35],[302,-379],[176,-14],[-469,-340],[22,-214],[-268,-111],[-61,-127],[165,-199],[-61,-122],[57,-258],[-271,-247],[215,-199],[-71,-101]],[[48721,69241],[-265,-25],[158,583],[-352,77],[30,244],[-118,25],[123,190],[-271,303],[199,305],[-183,-51],[506,308],[-96,118],[157,159],[-235,411],[-62,-82],[-185,145],[-128,-169],[-364,467],[-726,-740],[-122,-64]],[[56668,67736],[-428,233],[-191,-22],[99,368],[-213,218],[-363,54],[-218,282],[-111,243],[-193,-47],[-193,149],[-189,-127],[49,-105],[-154,-198],[-272,13],[-353,146],[-166,-255]],[[54251,67912],[29,-137],[-203,-421],[-15,-520],[367,-257],[15,-127],[246,-22],[117,-174]],[[53772,68688],[482,-248],[-109,-304],[116,-1],[-10,-223]],[[45071,72817],[533,268],[-64,133],[293,219],[460,454],[524,404],[238,264]],[[44610,74337],[-223,-373],[229,-70],[-34,-86],[164,-528],[-89,-248],[414,-215]],[[44971,75086],[42,-87],[-280,-71],[227,-268],[-350,-323]],[[47055,74559],[-252,210],[55,204],[-360,-50],[-688,237],[-839,-74]],[[41200,72801],[576,224],[3,218],[134,326],[294,272],[64,134],[246,-54],[161,-224],[228,143],[292,17],[403,-277],[186,-53]],[[44301,77210],[-392,51],[-181,178],[-427,-59]],[[44950,76502],[-163,206],[-334,-213],[-81,247],[70,160],[-181,-43],[40,351]],[[44971,75086],[-12,326],[190,173],[179,-19],[-220,507],[-30,347],[-128,82]],[[43787,73527],[172,25],[55,447],[-85,61],[370,472],[311,-195]],[[60443,75489],[-57,-109],[-242,31],[-16,-548],[-229,-18],[-164,-241],[119,-78],[-440,-545],[-111,-196]],[[62275,74614],[-404,353],[-92,136],[-744,835],[-497,-530],[-95,81]],[[59415,73725],[418,-179],[464,56],[28,-210],[-122,-202],[100,-236],[240,-129],[181,106],[223,-144],[1,-133]],[[59303,73785],[112,-60]],[[59304,72142],[215,-332],[419,-464],[225,-14],[170,152],[114,-49]],[[59415,73725],[-40,-372],[-164,-159],[146,-126],[-9,-291],[-294,-298],[250,-337]],[[50229,76563],[494,-1450],[244,-419],[294,-255],[-458,-265],[249,-40],[141,-356],[9,-311],[320,199]],[[54499,75539],[155,371],[377,382],[222,-70],[300,242],[136,192],[286,198],[-206,726],[-166,86],[-609,1797]],[[53509,74559],[-268,112],[368,332],[277,165],[185,248],[428,123]],[[51522,73666],[635,367],[164,-105],[189,46],[999,585]],[[52583,69346],[163,82],[264,-188]],[[52050,70131],[363,-502],[221,-181],[-51,-102]],[[53083,71482],[-90,-293],[-165,-88],[59,-145],[-530,-975],[6,364],[-63,82],[-250,-296]],[[54918,73399],[-255,-276],[-214,-121],[84,-252],[-328,-230],[-475,-250],[-206,-242],[-165,38],[-276,-584]],[[56156,73376],[-116,122],[108,159],[-105,76],[-265,-28],[-736,-419],[-124,113]],[[53010,69240],[187,318],[102,-27],[231,161],[261,85],[90,128],[461,40],[87,-127],[360,497],[353,316],[-116,353],[73,165],[223,183],[113,301],[356,283],[141,416],[196,105],[-67,130],[98,328],[-126,348],[123,133]],[[54443,74395],[-56,-225],[-196,-206],[-169,310],[-396,-324],[-130,192],[144,110],[10,199],[-141,108]],[[54918,73399],[77,313],[3,293],[-155,387],[-400,3]],[[51618,73439],[263,-234],[155,152],[179,-61],[-127,-82],[122,-228],[-72,-86],[458,-302],[-322,-248],[367,-276],[-173,-233],[115,-70],[-139,-187],[392,-229],[99,197],[148,-70]],[[51522,73666],[196,-93],[-100,-134]],[[58095,68266],[337,591],[537,109],[56,202],[460,476],[265,192],[404,857]],[[57455,69475],[178,-313],[119,-69],[55,-299]],[[59304,72142],[-214,-269],[-59,52],[-213,-314],[-114,94],[-69,-406],[-606,-765],[-423,-795],[83,-43],[-234,-221]],[[53010,69240],[131,-174],[157,239],[270,-193],[-207,-202],[411,-222]],[[57013,73094],[-301,177],[-424,173],[-132,-68]],[[57455,69475],[-308,108],[157,287],[0,359],[-203,25],[-181,159],[330,351],[-305,276],[174,187],[-269,261],[64,112],[283,81],[-279,241],[227,245],[-140,103],[132,185],[-160,204],[89,123],[-141,178],[88,134]],[[44974,70391],[-853,-457]],[[45871,71518],[-468,-413],[201,-657],[-167,-95],[-463,38]],[[46313,71935],[-442,-417]],[[46787,71445],[-157,-140],[-317,630]],[[45126,68958],[203,230],[106,-317],[266,-111],[162,118],[314,-98],[244,-245],[273,-109],[111,133]],[[44974,70391],[-167,113],[-1270,1441],[-99,171],[-11,329],[-95,52],[222,358],[-53,31],[228,346],[-99,59],[157,236]],[[58514,74187],[-152,-112],[-207,28],[-427,-575],[-87,7],[-359,-363],[-92,99],[-177,-177]],[[59303,73785],[-313,221],[-476,181]],[[47477,76250],[-375,-26],[-420,43],[-105,321],[-347,11],[-325,81],[-431,-121],[-284,39],[-240,-96]],[[47149,74486],[317,49],[-139,215],[237,46],[-65,123],[357,174],[-199,358],[452,434],[626,466]],[[47055,74559],[94,-73]],[[54251,67912],[-49,-66],[-395,-80],[-555,-227],[-236,-289],[-227,-544],[-190,-237],[-321,-120],[-298,-425]],[[44301,77210],[347,131],[247,-171],[195,28],[135,-94],[-98,230],[243,124],[-75,174],[166,46]],[[45257,79795],[-77,93],[-269,-47],[-306,-152],[-74,122],[-332,20],[-135,-192],[-354,-163],[102,-230],[-362,-197],[-64,86],[-175,-110],[84,-165],[-595,-114]],[[52583,69346],[-199,-737],[-192,-238],[-378,-647],[-213,-5],[-253,-769]],[[51270,70051],[56,90],[434,-446],[290,436]],[[49930,71463],[329,-41],[64,-344],[308,-524],[207,-266],[164,123],[195,-109],[73,-251]],[[51618,73439],[-400,-260],[-321,-113],[-255,-21],[-67,-117],[-504,-537],[-252,-320],[345,-183],[-56,-179],[-200,-125],[22,-121]],[[60526,77084],[-318,-317],[41,-181],[-381,-427],[-362,-237],[-137,-239],[42,-87],[-361,-58],[-544,-275],[-377,-345],[-25,-281],[-102,-90],[204,-187],[188,115],[233,-112],[-113,-176]],[[60443,75489],[222,515],[682,558],[52,150],[-311,406],[-397,-278],[-165,244]],[[45871,71518],[-520,933],[-151,-58],[-129,424]],[[46313,71935],[-279,576],[346,228],[20,221],[566,303],[344,146],[124,159],[-310,557],[101,253],[-76,108]],[[51270,70051],[16,-199],[-245,-270],[-110,106],[-384,-688],[122,-94],[-366,-520]],[[49930,71463],[-135,-81],[-140,-252],[-377,-452],[-209,15],[66,-284],[-71,-360],[24,-245]],[[54443,74395],[-156,28],[205,153],[-17,279],[-217,58],[242,294],[-100,105],[99,227]],[[60526,77084],[-789,791],[-2110,2405]]],"transform":{"scale":[0.004920362891052784,-0.004800048000480005],"translate":[233.98431562880634,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/vs.json b/src/onegov/election_day/static/mapdata/2025/vs.json new file mode 100644 index 0000000000..bb6879d4a5 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/vs.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":6002,"properties":{"id":6002,"name":"Brig-Glis"},"arcs":[[-1,-2,-3,-4,-5,-6,-7]]},{"type":"Polygon","id":6004,"properties":{"id":6004,"name":"Eggerberg"},"arcs":[[-8,-9,-10,-11,-12]]},{"type":"Polygon","id":6007,"properties":{"id":6007,"name":"Naters"},"arcs":[[6,-13,7,-14,-15,-16,-17,-18,-19,-20]]},{"type":"Polygon","id":6008,"properties":{"id":6008,"name":"Ried-Brig"},"arcs":[[-21,1,-22,-23,-24,-25]]},{"type":"Polygon","id":6009,"properties":{"id":6009,"name":"Simplon"},"arcs":[[-26,-27,-28,-29,-30,-31,2,20]]},{"type":"Polygon","id":6010,"properties":{"id":6010,"name":"Termen"},"arcs":[[19,-32,-33,-34,-35,21,0]]},{"type":"Polygon","id":6011,"properties":{"id":6011,"name":"Zwischbergen"},"arcs":[[24,-36,-37,25]]},{"type":"Polygon","id":6021,"properties":{"id":6021,"name":"Ardon"},"arcs":[[-38,-39,-40,-41]]},{"type":"Polygon","id":6022,"properties":{"id":6022,"name":"Chamoson"},"arcs":[[-42,-43,-44,40,-45,-46]]},{"type":"Polygon","id":6023,"properties":{"id":6023,"name":"Conthey"},"arcs":[[-47,-48,-49,-50,37,43,-51]]},{"type":"Polygon","id":6024,"properties":{"id":6024,"name":"Nendaz"},"arcs":[[44,39,-52,48,-53,-54,-55,-56,-57,-58,-59,-60,-61]]},{"type":"Polygon","id":6025,"properties":{"id":6025,"name":"Vétroz"},"arcs":[[51,38,49]]},{"type":"Polygon","id":6032,"properties":{"id":6032,"name":"Bourg-Saint-Pierre"},"arcs":[[-62,-63,-64,-65],[-66]]},{"type":"MultiPolygon","id":6033,"properties":{"id":6033,"name":"Liddes"},"arcs":[[[62,-67,-68]],[[65]]]},{"type":"Polygon","id":6034,"properties":{"id":6034,"name":"Orsières"},"arcs":[[-69,-70,-71,-72,66,61,-73,-74]]},{"type":"Polygon","id":6035,"properties":{"id":6035,"name":"Sembrancher"},"arcs":[[70,-75,-76]]},{"type":"Polygon","id":6037,"properties":{"id":6037,"name":"Val de Bagnes"},"arcs":[[63,67,71,75,-77,-78,-79,-80,57,-81,-82,-83]]},{"type":"Polygon","id":6052,"properties":{"id":6052,"name":"Bellwald"},"arcs":[[-84,-85,-86,-87]]},{"type":"Polygon","id":6054,"properties":{"id":6054,"name":"Binn"},"arcs":[[-88,-89,-90,-91]]},{"type":"Polygon","id":6056,"properties":{"id":6056,"name":"Ernen"},"arcs":[[-92,-93,-94,86,-95,88]]},{"type":"Polygon","id":6057,"properties":{"id":6057,"name":"Fiesch"},"arcs":[[93,-96,-97,-98,83]]},{"type":"Polygon","id":6058,"properties":{"id":6058,"name":"Fieschertal"},"arcs":[[97,-99,15,-100,-101,-102,84]]},{"type":"Polygon","id":6061,"properties":{"id":6061,"name":"Lax"},"arcs":[[95,92,-103,-104]]},{"type":"Polygon","id":6076,"properties":{"id":6076,"name":"Obergoms"},"arcs":[[-105,-106]]},{"type":"Polygon","id":6077,"properties":{"id":6077,"name":"Goms"},"arcs":[[89,94,85,101,-107,104,-108]]},{"type":"Polygon","id":6082,"properties":{"id":6082,"name":"Ayent"},"arcs":[[-109,-110,-111,-112,-113,-114,-115]]},{"type":"Polygon","id":6083,"properties":{"id":6083,"name":"Evolène"},"arcs":[[-116,-117,-118,-119,81,-120]]},{"type":"Polygon","id":6084,"properties":{"id":6084,"name":"Hérémence"},"arcs":[[119,80,56,-121,-122]]},{"type":"Polygon","id":6087,"properties":{"id":6087,"name":"Saint-Martin (VS)"},"arcs":[[121,-123,-124,-125,115]]},{"type":"Polygon","id":6089,"properties":{"id":6089,"name":"Vex"},"arcs":[[-126,-127,122,120,55]]},{"type":"Polygon","id":6090,"properties":{"id":6090,"name":"Mont-Noble"},"arcs":[[-128,123,126,-129,-130]]},{"type":"Polygon","id":6101,"properties":{"id":6101,"name":"Agarn"},"arcs":[[-131,-132,-133,-134]]},{"type":"Polygon","id":6102,"properties":{"id":6102,"name":"Albinen"},"arcs":[[-135,-136,-137,-138]]},{"type":"Polygon","id":6104,"properties":{"id":6104,"name":"Ergisch"},"arcs":[[-139,-140,-141,-142,-143,-144,-145]]},{"type":"Polygon","id":6109,"properties":{"id":6109,"name":"Inden"},"arcs":[[-146,-147,135,-148,-149]]},{"type":"Polygon","id":6110,"properties":{"id":6110,"name":"Leuk"},"arcs":[[-150,-151,147,134,-152,-153,-154,-155,132,-156]]},{"type":"Polygon","id":6111,"properties":{"id":6111,"name":"Leukerbad"},"arcs":[[-157,-158,-159,136,146,-160]]},{"type":"Polygon","id":6112,"properties":{"id":6112,"name":"Oberems"},"arcs":[[-161,-162,130,-163,138]]},{"type":"Polygon","id":6113,"properties":{"id":6113,"name":"Salgesch"},"arcs":[[-164,-165,-166,-167,-168,149]]},{"type":"Polygon","id":6116,"properties":{"id":6116,"name":"Varen"},"arcs":[[148,150,167,-169]]},{"type":"Polygon","id":6117,"properties":{"id":6117,"name":"Guttet-Feschel"},"arcs":[[137,158,-170,151]]},{"type":"Polygon","id":6118,"properties":{"id":6118,"name":"Gampel-Bratsch"},"arcs":[[-171,153,-172,-173]]},{"type":"MultiPolygon","id":6119,"properties":{"id":6119,"name":"Turtmann-Unterems"},"arcs":[[[144,-174,-175,160]],[[-176,-177,139,162,133,154,170,-178]]]},{"type":"Polygon","id":6131,"properties":{"id":6131,"name":"Bovernier"},"arcs":[[-179,76,74,69,-180]]},{"type":"Polygon","id":6133,"properties":{"id":6133,"name":"Fully"},"arcs":[[-181,-182,-183,-184,-185,-186,-187,-188,-189]]},{"type":"Polygon","id":6134,"properties":{"id":6134,"name":"Isérables"},"arcs":[[-190,59]]},{"type":"Polygon","id":6135,"properties":{"id":6135,"name":"Leytron"},"arcs":[[188,-191,41,-192,-193,181,-194]]},{"type":"Polygon","id":6136,"properties":{"id":6136,"name":"Martigny"},"arcs":[[-195,-196,-197,-198,184,-199,77,178]]},{"type":"Polygon","id":6137,"properties":{"id":6137,"name":"Martigny-Combe"},"arcs":[[-200,-201,194,179,68]]},{"type":"Polygon","id":6139,"properties":{"id":6139,"name":"Riddes"},"arcs":[[45,60,189,58,79,-202,-203,191]]},{"type":"MultiPolygon","id":6140,"properties":{"id":6140,"name":"Saillon"},"arcs":[[[192,202,-204,182]],[[193,180]]]},{"type":"Polygon","id":6141,"properties":{"id":6141,"name":"Saxon"},"arcs":[[78,198,183,203,201]]},{"type":"Polygon","id":6142,"properties":{"id":6142,"name":"Trient"},"arcs":[[73,-205,-206,-207,199]]},{"type":"Polygon","id":6151,"properties":{"id":6151,"name":"Champéry"},"arcs":[[-208,-209,-210]]},{"type":"Polygon","id":6152,"properties":{"id":6152,"name":"Collombey-Muraz"},"arcs":[[-211,-212,-213,-214,-215,-216,-217,-218],[-219]]},{"type":"MultiPolygon","id":6153,"properties":{"id":6153,"name":"Monthey"},"arcs":[[[-220,-221,-222,-223,210]],[[-224,-225,-226]],[[-227,214]],[[218]]]},{"type":"Polygon","id":6154,"properties":{"id":6154,"name":"Port-Valais"},"arcs":[[-228,-229,-230]]},{"type":"Polygon","id":6155,"properties":{"id":6155,"name":"Saint-Gingolph"},"arcs":[[229,-231,-232]]},{"type":"Polygon","id":6156,"properties":{"id":6156,"name":"Troistorrents"},"arcs":[[-233,211,222,-234,-235,223]]},{"type":"Polygon","id":6157,"properties":{"id":6157,"name":"Val-d'Illiez"},"arcs":[[-236,208,-237,224,234,-238,-239]]},{"type":"Polygon","id":6158,"properties":{"id":6158,"name":"Vionnaz"},"arcs":[[215,226,213,-240,-241]]},{"type":"Polygon","id":6159,"properties":{"id":6159,"name":"Vouvry"},"arcs":[[240,-242,230,228,-243,216]]},{"type":"Polygon","id":6172,"properties":{"id":6172,"name":"Bister"},"arcs":[[-244,-245]]},{"type":"Polygon","id":6173,"properties":{"id":6173,"name":"Bitsch"},"arcs":[[31,18,-246]]},{"type":"Polygon","id":6177,"properties":{"id":6177,"name":"Grengiols"},"arcs":[[-247,22,34,-248,243,-249,-250,102,91,87]]},{"type":"Polygon","id":6181,"properties":{"id":6181,"name":"Riederalp"},"arcs":[[245,17,-251,-252,32]]},{"type":"Polygon","id":6191,"properties":{"id":6191,"name":"Ausserberg"},"arcs":[[-253,-254,-255,10]]},{"type":"Polygon","id":6192,"properties":{"id":6192,"name":"Blatten"},"arcs":[[99,14,-256,-257,-258,-259]]},{"type":"Polygon","id":6193,"properties":{"id":6193,"name":"Bürchen"},"arcs":[[-260,-261,-262,-263]]},{"type":"Polygon","id":6194,"properties":{"id":6194,"name":"Eischoll"},"arcs":[[-264,140,176,-265]]},{"type":"Polygon","id":6195,"properties":{"id":6195,"name":"Ferden"},"arcs":[[152,169,157,-266,-267,-268,-269,171]]},{"type":"Polygon","id":6197,"properties":{"id":6197,"name":"Kippel"},"arcs":[[-270,266,-271,-272]]},{"type":"Polygon","id":6198,"properties":{"id":6198,"name":"Niedergesteln"},"arcs":[[-273,-274,264,175,-275,267,269,-276]]},{"type":"Polygon","id":6199,"properties":{"id":6199,"name":"Raron"},"arcs":[[272,-277,256,-278,253,-279,-280,-281,262,-282]]},{"type":"Polygon","id":6201,"properties":{"id":6201,"name":"Unterbäch"},"arcs":[[-283,-284,141,263,273,281,261]]},{"type":"Polygon","id":6202,"properties":{"id":6202,"name":"Wiler (Lötschen)"},"arcs":[[275,271,-285,257,276]]},{"type":"Polygon","id":6203,"properties":{"id":6203,"name":"Mörel-Filet"},"arcs":[[251,-286,248,244,247,33]]},{"type":"Polygon","id":6204,"properties":{"id":6204,"name":"Steg-Hohtenn"},"arcs":[[172,268,274,177]]},{"type":"Polygon","id":6205,"properties":{"id":6205,"name":"Bettmeralp"},"arcs":[[285,250,16,98,96,103,249]]},{"type":"Polygon","id":6211,"properties":{"id":6211,"name":"Collonges"},"arcs":[[-287,-288,-289,-290,186]]},{"type":"Polygon","id":6212,"properties":{"id":6212,"name":"Dorénaz"},"arcs":[[185,197,-291,-292,286]]},{"type":"Polygon","id":6213,"properties":{"id":6213,"name":"Evionnaz"},"arcs":[[209,235,-293,287,291,-294,-295,-296]]},{"type":"Polygon","id":6214,"properties":{"id":6214,"name":"Finhaut"},"arcs":[[-297,-298,205]]},{"type":"Polygon","id":6215,"properties":{"id":6215,"name":"Massongex"},"arcs":[[220,-299,-300,-301]]},{"type":"Polygon","id":6217,"properties":{"id":6217,"name":"Saint-Maurice"},"arcs":[[238,-302,299,-303,288,292]]},{"type":"Polygon","id":6218,"properties":{"id":6218,"name":"Salvan"},"arcs":[[294,-304,195,200,206,297,-305]]},{"type":"Polygon","id":6219,"properties":{"id":6219,"name":"Vernayaz"},"arcs":[[303,293,290,196]]},{"type":"Polygon","id":6220,"properties":{"id":6220,"name":"Vérossaz"},"arcs":[[233,221,300,301,237]]},{"type":"Polygon","id":6232,"properties":{"id":6232,"name":"Chalais"},"arcs":[[-306,-307,-308,-309]]},{"type":"Polygon","id":6235,"properties":{"id":6235,"name":"Chippis"},"arcs":[[-310,-311,306]]},{"type":"Polygon","id":6238,"properties":{"id":6238,"name":"Grône"},"arcs":[[129,-312,-313,-314,308,-315]]},{"type":"Polygon","id":6239,"properties":{"id":6239,"name":"Icogne"},"arcs":[[-316,111,-317,-318,-319]]},{"type":"Polygon","id":6240,"properties":{"id":6240,"name":"Lens"},"arcs":[[-320,318,-321,-322]]},{"type":"Polygon","id":6246,"properties":{"id":6246,"name":"Saint-Léonard"},"arcs":[[-323,312,-324,112,315,319]]},{"type":"Polygon","id":6248,"properties":{"id":6248,"name":"Sierre"},"arcs":[[321,-325,-326,164,-327,309,305,313,322]]},{"type":"Polygon","id":6252,"properties":{"id":6252,"name":"Anniviers"},"arcs":[[127,314,307,310,326,163,155,131,161,-328,-329,-330,116,124]]},{"type":"Polygon","id":6253,"properties":{"id":6253,"name":"Crans-Montana"},"arcs":[[168,166,-331,324,320,317,-332,159,145]]},{"type":"Polygon","id":6254,"properties":{"id":6254,"name":"Noble-Contrée"},"arcs":[[330,165,325]]},{"type":"Polygon","id":6261,"properties":{"id":6261,"name":"Arbaz"},"arcs":[[-333,-334,108]]},{"type":"Polygon","id":6263,"properties":{"id":6263,"name":"Grimisuat"},"arcs":[[114,-335,-336,332]]},{"type":"Polygon","id":6265,"properties":{"id":6265,"name":"Savièse"},"arcs":[[-337,109,333,335,-338,46]]},{"type":"Polygon","id":6266,"properties":{"id":6266,"name":"Sion"},"arcs":[[54,-339,52,47,337,334,113,323,311,128,125]]},{"type":"Polygon","id":6267,"properties":{"id":6267,"name":"Veysonnaz"},"arcs":[[53,338]]},{"type":"MultiPolygon","id":6281,"properties":{"id":6281,"name":"Baltschieder"},"arcs":[[[255,13,11,254,277]],[[-340,278,252,9,-341]]]},{"type":"Polygon","id":6282,"properties":{"id":6282,"name":"Eisten"},"arcs":[[-342,-343,-344,-345,-346,29,-347]]},{"type":"Polygon","id":6283,"properties":{"id":6283,"name":"Embd"},"arcs":[[-348,142,283,-349,-350]]},{"type":"Polygon","id":6285,"properties":{"id":6285,"name":"Grächen"},"arcs":[[349,-351,-352,342,-353]]},{"type":"Polygon","id":6286,"properties":{"id":6286,"name":"Lalden"},"arcs":[[340,8,12,5,-354]]},{"type":"Polygon","id":6287,"properties":{"id":6287,"name":"Randa"},"arcs":[[-355,327,174,-356,-357]]},{"type":"Polygon","id":6288,"properties":{"id":6288,"name":"Saas-Almagell"},"arcs":[[-358,-359,26,36,-360,-361,-362]]},{"type":"Polygon","id":6289,"properties":{"id":6289,"name":"Saas-Balen"},"arcs":[[346,28,-363,-364,-365]]},{"type":"Polygon","id":6290,"properties":{"id":6290,"name":"Saas-Fee"},"arcs":[[-366,356,-367,363,-368,357]]},{"type":"Polygon","id":6291,"properties":{"id":6291,"name":"Saas-Grund"},"arcs":[[367,362,27,358]]},{"type":"Polygon","id":6292,"properties":{"id":6292,"name":"St. Niklaus"},"arcs":[[352,341,364,366,355,173,143,347]]},{"type":"Polygon","id":6293,"properties":{"id":6293,"name":"Stalden (VS)"},"arcs":[[-369,-370,-371,343,351,-372]]},{"type":"Polygon","id":6294,"properties":{"id":6294,"name":"Staldenried"},"arcs":[[-373,344,370]]},{"type":"Polygon","id":6295,"properties":{"id":6295,"name":"Täsch"},"arcs":[[361,-374,328,354,365]]},{"type":"Polygon","id":6296,"properties":{"id":6296,"name":"Törbel"},"arcs":[[371,350,348,282,260,-375]]},{"type":"Polygon","id":6297,"properties":{"id":6297,"name":"Visp"},"arcs":[[279,339,353,4,-376,-377]]},{"type":"Polygon","id":6298,"properties":{"id":6298,"name":"Visperterminen"},"arcs":[[-378,375,3,30,345,372,369]]},{"type":"Polygon","id":6299,"properties":{"id":6299,"name":"Zeneggen"},"arcs":[[374,259,280,376,377,368]]},{"type":"Polygon","id":6300,"properties":{"id":6300,"name":"Zermatt"},"arcs":[[373,360,-379,117,329]]}]}},"arcs":[[[72236,57769],[158,301],[-97,182]],[[74001,52183],[-218,1045],[-214,635],[-25,178],[-409,301],[-39,231],[-270,405],[-86,364],[-98,35],[-30,233],[-187,74],[87,267],[-49,228],[-219,234],[100,217],[-66,413],[308,359],[-194,55],[-180,139],[24,173]],[[71195,50459],[272,-147],[89,-291],[200,-317],[222,226],[341,9],[145,119],[120,295],[212,-20],[367,120],[155,149],[227,327],[37,148],[419,1106]],[[68142,53352],[145,170],[295,26],[272,-186],[136,-194],[-164,-183],[0,-450],[133,-251],[202,-795],[139,-251],[-6,-126],[151,-319],[21,-264],[55,431],[208,-11],[126,435],[253,-6],[332,-315],[451,-174],[145,43],[65,163],[94,-636]],[[67021,55123],[88,-154],[716,142],[-59,-850],[29,-183],[347,-726]],[[66892,55716],[2,-354],[127,-239]],[[72297,58252],[-1139,-379],[-1108,-831],[-558,-433],[-272,-309],[-415,-267],[-64,270],[-253,-126],[-538,-136],[-49,74],[-264,-172],[-242,-50],[-325,-183],[-178,6]],[[66517,55756],[18,581],[85,127],[-255,217],[-61,-96],[-75,123],[159,158],[35,169],[231,72],[-86,688],[-83,149],[-116,-5],[-94,139],[3,311],[-251,4],[-164,-103],[-68,322],[60,131],[-82,311],[-303,807],[-56,419]],[[65032,55948],[192,-241],[199,-95],[527,37],[169,168],[398,-61]],[[65144,57816],[0,-597],[-57,-142],[-525,-417],[-160,-448],[63,-203],[567,-61]],[[65143,57985],[1,-169]],[[65414,60280],[-357,-164],[107,-1131],[19,-439],[-40,-561]],[[66517,55756],[258,-81],[117,41]],[[65865,70198],[227,-169],[387,-532],[269,-186],[167,-505],[4,-220],[-111,-496],[59,-258],[-21,-475],[-89,-316],[26,-478],[-132,-327],[182,-260],[147,-66],[-4,-282],[98,-327],[-107,-533],[-11,-332],[-100,-353],[-18,-223],[-122,-120],[-317,-82],[-254,-278],[-35,-297],[54,-129],[-14,-298],[119,-339],[-109,-372],[-82,-137],[-271,11],[-285,-228],[-182,-206],[27,-791],[47,-314]],[[70035,76375],[-306,-125],[-244,-369],[-24,-189],[-145,-359],[-241,-335],[0,-211],[-156,-518],[-196,-331],[-296,-368],[-129,-244],[-308,-245],[-59,-132],[-215,-144],[-147,-393],[-193,-110],[-227,-342],[-135,-331],[-152,-80],[-142,-174],[-131,-463],[-228,-134],[-19,-115],[-243,-132],[-200,-206],[-34,-127]],[[71575,76151],[-243,77],[-313,173],[-342,-80],[-245,202],[-324,-37],[-73,-111]],[[75268,69447],[163,435],[69,573],[90,475],[106,314],[232,460],[172,272],[-798,1107],[-216,177],[-243,114],[-1476,1725],[-1696,936],[-96,116]],[[72302,64594],[-23,446],[-63,213],[183,488],[27,242],[174,226],[16,149],[143,210],[7,190],[532,720],[440,314],[196,191],[349,624],[371,260],[407,331],[207,249]],[[72900,59095],[-95,262],[-156,183],[-126,-28],[-76,267],[-185,20],[-87,280],[-18,403],[-182,598],[-63,587],[60,614],[-94,111],[53,115],[25,453],[-20,254],[162,144],[77,263],[-3,354],[97,330],[33,289]],[[72297,58252],[268,295],[147,100],[142,234],[46,214]],[[74001,52183],[142,-531],[19,-319],[65,-309],[-19,-196],[92,-247],[46,-386],[182,-313],[126,-25],[281,-515],[122,29],[240,-244],[146,-246],[238,-515],[107,-131],[305,-163],[675,182],[175,105],[245,30]],[[78210,57213],[-141,-214],[40,-59],[55,-635],[-254,-197],[-133,-251],[-203,-192],[-342,-123],[-253,-143],[-270,75],[-98,110],[-120,-61],[-55,354],[23,163],[-67,253],[-124,-414],[-173,-98],[-348,-77],[-104,153],[-104,-3],[-42,150],[-95,-63],[-418,-47],[-246,-150],[-383,-14],[168,378],[194,146],[103,199],[2,260],[275,111],[240,370],[15,230],[-159,409],[-53,24],[-85,-245],[-60,240],[69,388],[-34,385],[-408,-349],[-335,-202],[-409,160],[-256,39],[-507,-206],[-233,-52],[-97,90],[-360,-110],[-189,-226]],[[80433,55743],[-123,114],[-351,448],[-124,22],[27,126],[-93,420],[-42,-65],[-231,20],[-360,337],[-166,17],[-314,166],[-160,-53],[-54,92],[-232,-174]],[[78157,49128],[1,354],[-198,111],[-64,-87],[-429,99],[-217,114],[-50,191],[-132,50],[-90,165],[-75,383],[229,43],[116,207],[-25,503],[236,145],[188,192],[42,131],[174,140],[75,204],[128,74],[193,369],[102,389],[386,98],[171,258],[93,340],[101,110],[20,359],[135,286],[-10,90],[251,334],[216,32],[118,322],[437,584],[154,25]],[[77188,48389],[281,202],[126,160],[293,154],[269,223]],[[73205,33593],[177,-149],[191,-377],[197,-117],[274,18],[257,180],[180,186],[56,1010],[-58,283],[-122,280],[-45,923],[104,437],[311,457],[361,150],[116,263],[146,67],[149,289],[96,75],[59,258],[175,198],[10,112],[252,344],[138,570],[76,63],[192,436],[-39,55],[97,554],[-10,251],[47,450],[232,240],[199,-16],[133,124],[202,-125],[259,72],[351,298],[110,260],[303,231],[21,144],[289,165],[178,47],[143,264],[-127,79],[-143,441],[-160,129],[-66,232],[86,219],[-70,305],[30,95],[-65,350],[-161,249],[-178,147],[-186,6],[-152,121],[-44,388],[-105,98],[-87,392],[-27,551],[-601,792],[98,76],[75,283],[-34,167],[45,285],[120,309],[-72,112]],[[72961,33838],[244,-245]],[[72424,38876],[322,149],[98,-89],[30,-240],[-194,-276],[-173,-122],[-9,-253],[-84,-312],[0,-213],[160,-570],[-43,-311],[174,-735],[-41,-458],[53,-233],[185,-302],[81,-363],[-58,-298],[36,-412]],[[71947,40263],[-17,-228],[71,-386],[-12,-207],[230,-368],[205,-198]],[[71878,41061],[120,-241],[-51,-557]],[[71195,50459],[-96,-379],[36,-596],[148,-523],[-55,-415],[-226,-418],[59,-450],[-63,-317],[100,-422],[-59,-344],[29,-559],[128,-240],[47,-397],[-57,-476],[20,-667],[193,-334],[221,-583],[135,-7],[177,-229],[-289,-774],[97,-174],[-19,-200],[108,-452],[-18,-171],[67,-271]],[[73662,60699],[23,-183],[-98,-207],[-269,-201],[-268,-423],[-150,-590]],[[73742,60969],[-80,-270]],[[77551,59046],[-252,-245],[-244,-135],[-345,227],[-58,466],[-142,201],[-328,300],[-357,35],[-154,137],[-235,50],[-79,122],[-147,13],[-259,138],[-282,9],[-179,305],[-246,111],[-385,318],[-117,-129]],[[78210,57213],[-101,161],[-164,506],[-230,236],[87,139],[-143,278],[-108,513]],[[74323,30489],[240,-100],[126,86],[124,-94],[289,189],[67,109],[330,-111],[244,163],[301,283],[483,187],[301,-3],[202,-116],[572,292],[381,115],[194,322],[72,-77],[273,163],[124,-6],[94,194],[11,258],[164,123],[60,186],[-12,258],[88,342],[-60,208],[96,404],[-21,388],[377,303],[79,252],[590,242],[170,32],[110,-138],[238,28],[236,217],[284,595],[12,110],[232,537],[-127,105],[-9,685],[-207,405],[-6,537],[64,406],[102,199],[188,210],[55,169],[51,438],[127,265],[324,252],[40,444],[-59,302],[-464,825],[-234,194],[-109,970],[-11,495],[-470,1091],[-284,1817],[-310,35],[-197,194],[-175,28],[-180,166],[-6,220],[-277,631],[-247,-48],[-36,228],[-112,130],[-80,271],[24,488],[-108,553],[-281,71],[-223,-78]],[[73205,33593],[147,-777],[13,-487],[195,-156],[20,-219],[184,-361],[136,-396],[123,-132],[300,-576]],[[26297,50460],[-272,-397],[-262,-209],[-269,-430],[-36,-419],[-125,-55],[-270,-570],[-82,-106],[-112,-508]],[[30011,42610],[-81,293],[-703,1096],[-292,375],[-318,282],[-279,325],[-218,403],[78,341],[-72,196],[120,428],[10,683],[43,228],[13,414],[-85,128],[-26,392],[-59,-22],[-65,226],[27,303],[-87,275],[-220,513],[-9,239],[-106,220],[-72,389],[-86,51],[-894,-118],[-59,-89],[-274,279]],[[29120,41850],[605,536],[286,224]],[[24869,47766],[367,-120],[103,-137],[247,-57],[140,-248],[172,-92],[119,-276],[184,-149],[135,-272],[171,-220],[156,-355],[-15,-167],[189,-450],[51,-245],[75,-47],[120,-503],[78,34],[117,-329],[12,-191],[196,-71],[-17,-142],[286,-230],[28,-129],[-22,-657],[89,-83],[-117,-209],[226,-196],[322,-386],[218,302],[81,188],[540,-479]],[[21066,47352],[119,-308],[110,-549],[229,-278],[793,-1647],[209,-187],[113,-263],[365,-14],[623,-592],[226,-590],[165,-72],[182,111],[280,-13],[192,-98],[127,-152],[194,-103],[148,-316],[108,84],[172,-97],[245,33],[266,-148],[227,-217],[192,357],[110,-341],[62,-465],[27,-521],[-20,-935]],[[22292,48304],[-67,-177],[-281,-178],[-171,-357],[-192,-177],[-235,-93],[-280,30]],[[24869,47766],[-96,-17],[-266,-213],[-185,55],[-161,-142],[-239,-73],[-140,-164],[-118,179],[-275,-21],[-107,-91],[-474,1121],[-203,46],[-313,-142]],[[28059,40680],[360,282],[418,621],[283,267]],[[26530,40031],[328,-196],[108,36],[156,336],[159,173],[412,137],[366,163]],[[31737,46825],[-119,351],[113,600],[-115,145],[-84,277],[138,215],[-59,114],[33,249],[125,340],[-28,182],[59,185],[218,261],[-34,173],[151,456],[-13,138],[114,405],[-39,153],[187,323],[-38,282],[140,161],[-18,86],[116,319],[139,177],[97,300],[12,250],[-99,970],[111,566],[-93,159],[-152,466],[-239,89],[-119,122],[-181,55],[-267,455],[-277,253],[-342,582],[-449,-102],[-108,-72],[-820,129],[-90,168],[-189,12],[-2890,-405],[-163,161],[3,268],[-271,309],[-203,132],[-206,-21],[-262,-213],[-304,-184]],[[31777,43955],[-352,787],[-69,275],[99,272],[346,522],[-16,594],[-48,420]],[[31149,43223],[488,629],[140,103]],[[26297,50460],[273,236],[464,644],[408,99],[135,-298],[107,86],[104,-113],[30,-337],[-35,-704],[189,-291],[29,-310],[163,-574],[59,53],[108,-183],[50,-445],[137,-99],[24,-288],[78,-218],[-6,-383],[-47,-366],[41,-540],[-157,-477],[66,-184],[-12,-395],[107,-61],[287,384],[180,120],[351,447],[131,23],[187,395],[97,87],[77,-189],[154,103],[448,-105],[29,-162],[190,-151],[-59,-405],[214,-799],[69,-46],[-193,-186],[-180,-78],[28,-342],[48,-6],[97,-465],[169,-36],[23,-215],[190,-463]],[[25222,56866],[-687,-1138],[8,-1091],[451,-758],[-180,-93],[55,-338],[-108,-100],[-159,17],[-235,-270],[62,-557],[118,-686],[-59,-280],[-277,-274],[-327,16],[-146,-353],[-218,-388],[-28,-194],[-136,-101],[-236,-491],[-272,-390],[-315,-56],[-205,-584],[-36,-453]],[[31149,43223],[-476,-380],[-662,-233]],[[33493,43336],[-207,376],[-108,415],[-425,-386],[-184,-78],[-473,-366],[-319,658]],[[33835,41879],[-459,-18],[-129,-238],[-495,150],[109,378],[35,324],[236,201],[-61,288],[422,372]],[[35029,39954],[-126,472],[-500,667],[-36,255],[-257,406],[-275,125]],[[34784,37722],[17,213],[102,270],[97,84],[63,586],[-53,169],[-7,448],[26,462]],[[34207,25251],[150,174],[-125,506],[-153,130],[-26,225],[41,326],[243,684],[455,709],[23,186],[-162,244],[-34,352],[76,225],[-149,354],[-192,605],[-4,208],[156,129],[71,386],[-174,379],[-17,735],[25,62],[-215,413],[7,405],[-68,197],[-160,135],[-137,431],[-18,355],[-192,258],[370,571],[7,538],[208,416],[-70,407],[99,251],[-35,254],[40,244],[101,174],[35,428],[51,99],[350,276]],[[29788,29811],[436,-358],[4,-287],[104,-221],[181,-182],[294,-194],[315,-377],[124,-351],[311,-318],[283,44],[140,-57],[144,229],[139,-122],[35,-166],[193,-351],[208,-97],[166,5],[44,-660],[161,-87],[-10,-389],[262,-21],[94,-354],[365,36],[275,-90],[151,-192]],[[29669,32115],[23,-271],[77,-241],[65,-608],[-9,-225],[-72,-162],[119,-476],[-84,-321]],[[28153,40538],[61,-351],[-131,-714],[324,37],[81,-533],[249,-541],[421,-486],[177,63],[359,-201],[-93,-229],[331,-115],[298,-282],[149,-48],[140,92],[73,-59],[13,-360],[69,-309],[-38,-646],[129,-332],[-43,-279],[-120,-101],[-3,-168],[-157,-408],[-16,-366],[112,-263],[-5,-203],[-150,-269],[-46,-378],[41,-85],[-90,-336],[-172,-12],[-250,-391],[-197,-150]],[[28059,40680],[94,-142]],[[21386,6968],[161,-439],[-11,-450],[193,-522],[-13,-303],[67,-217],[85,-45],[3,-581],[81,-366],[204,-537],[162,-888]],[[28756,12855],[-181,60],[-210,221],[-284,-199],[-144,92],[-101,-42],[-379,196],[-516,-51],[-288,279],[-265,57],[3,141],[-162,231],[-65,493],[-266,148],[-6,-151],[139,-375],[-173,-165],[-209,18],[57,203],[-83,379],[-213,-115],[-197,61],[59,-125],[-371,-380],[-284,-156],[-67,-836],[-322,-202],[-339,-42],[-365,104],[-202,-325],[-93,-540],[-104,-286],[-114,-608],[49,-638],[-154,-448],[-109,-199],[-153,-673],[-33,-440],[-125,-299],[-112,-121],[-191,-349],[-167,-192],[-330,-217],[-300,-396]],[[30662,7911],[-14,203],[117,402],[6,195],[144,337],[117,602],[-117,195],[-414,-13],[-116,101],[-406,-171],[-303,89],[-15,369],[-134,184],[-203,457],[-59,13],[-176,357],[-178,219],[-30,349],[60,131],[-126,198],[-5,534],[-54,193]],[[22318,2620],[183,-13],[294,-131],[176,-298],[-23,-265],[-172,-181],[37,-114],[789,-1050],[222,79],[304,-428],[147,-7],[231,-177],[194,156],[154,40],[246,352],[-129,357],[1,350],[-47,200],[162,636],[187,118],[152,475],[226,49],[57,172],[274,261],[56,596],[207,54],[187,133],[164,-71],[148,281],[182,-38],[233,-184],[309,-23],[266,143],[140,222],[179,-12],[76,-145],[81,-406],[221,-44],[126,127],[83,265],[171,267],[92,27],[107,221],[1,140],[210,214],[79,214],[320,94],[184,804],[210,604],[70,106],[66,423],[216,167],[50,310],[245,221]],[[25270,13230],[-93,-321],[-7,-271],[-179,80],[19,587],[-67,384],[181,132],[152,16],[-40,-397],[34,-210]],[[25149,19940],[-673,141],[-1234,341],[-108,-98],[-189,-333],[-135,-139],[-139,47],[-211,-314],[-176,-456],[-418,-594],[99,-567],[30,-393],[115,-234],[-76,-209],[-11,-538],[-60,-334],[36,-86],[-28,-453],[-126,-437],[10,-349],[-75,-302],[38,-269],[-135,-498],[43,-116],[-238,-869],[122,-142],[73,-222],[-205,-418],[95,-246],[-141,-328],[-161,-106],[-55,-253],[-25,-937],[-165,-298],[4,-301],[-127,-118],[-150,-485],[-189,-317],[21,-296],[171,-363],[144,-896],[328,-62],[158,-125]],[[28756,12855],[222,399],[114,101],[179,-66],[61,82],[2,495],[-31,354],[-77,153],[-28,271],[-128,158],[-121,284],[-87,357],[73,273],[-304,173],[-207,250],[-251,37],[-122,181],[-304,173],[-201,175],[-244,857],[-65,403],[18,225],[-192,325],[-82,375],[-297,-33],[-182,131],[-197,39],[-338,176],[-209,242],[-507,103],[-102,392]],[[16342,20936],[-75,60],[-414,-104],[-174,-250]],[[19575,25209],[-312,88],[-305,-266],[-638,-700],[-59,-689],[-131,-273],[-341,-462],[-495,-425],[-247,-533],[-40,-335],[-175,-192],[-203,-63],[-287,-423]],[[24141,24323],[-566,287],[-248,46],[-336,128],[-148,102],[-88,-61],[-282,27],[-117,114],[-159,11],[-108,250],[-257,-125],[-212,4],[-420,-136],[-404,141],[60,-217],[-170,-173],[-273,-140],[-264,-244],[-214,-104],[-92,285],[21,233],[-174,132],[-115,326]],[[25149,19940],[35,357],[-49,196],[26,351],[-61,102],[-105,573],[52,481],[-575,1004],[-111,372],[-7,246],[-236,432],[23,269]],[[14598,15346],[75,-173],[-126,-352],[-368,-149],[-303,-239],[-100,-525],[119,-75],[125,-417],[160,-329],[122,-138],[-2,-122],[149,0],[33,-143],[178,-133],[671,-267],[152,-238],[-46,-175],[60,-271],[-13,-281],[58,-101],[-3,-318],[-108,-199],[34,-111],[-33,-350],[-60,-188],[161,-621],[154,-180],[92,-287],[60,-810],[220,-272],[330,-677],[302,-252],[139,-28],[227,-504],[-43,-427],[31,-208],[-5,-528],[330,-259],[102,-257],[157,-126],[142,24],[-12,-611],[105,-177],[59,-331],[152,-282],[212,-121],[113,-234],[358,-460],[109,-207],[-108,-191],[-81,-283],[101,-91],[153,-408],[3,-174],[92,-373],[-36,-157],[147,-182],[72,-218],[156,16],[297,-156],[191,153],[381,1],[119,254],[256,322],[110,-9],[184,302],[101,54],[123,219],[-1,302],[103,205],[264,150],[69,181],[364,100],[102,161],[173,54],[116,171]],[[15679,20642],[-33,-503],[16,-429],[-262,-505],[-44,-553],[72,-31],[229,-535],[224,-78],[49,-117],[-19,-369],[-363,-448],[11,-129],[394,-797],[-135,-211],[-240,-201],[-47,49],[-355,-209],[-271,132],[-251,-203],[-56,-159]],[[19753,28658],[-302,-634],[3,-300],[71,-280],[110,-1801],[51,-151],[-111,-283]],[[24141,24323],[63,269],[-50,364],[-109,316],[114,106],[88,402],[78,138],[335,864],[45,280],[-21,251],[-190,595],[-60,267],[7,285],[-178,-145],[-119,-404],[-210,-229],[-548,-24],[-651,-145],[-232,209],[-118,-92],[-487,83],[-388,34],[-323,-55],[-209,-154],[-116,64],[-180,-112],[3,665],[-262,392],[-121,-55],[-30,220],[-176,47],[-303,-24],[-40,-77]],[[18804,28839],[221,-6],[74,-132],[167,53],[215,-147],[272,51]],[[22226,31995],[-142,-241],[-338,-823],[-249,-309],[-206,-185],[-651,-463],[-396,-247],[-554,-191],[-236,-193],[-322,-139],[-145,-224],[-111,82],[-72,-223]],[[26540,33138],[-103,32],[-204,-148],[-191,-46],[-205,39],[-81,-306],[-89,-95],[-208,97],[-165,-100],[-43,-133],[-123,12],[-65,-320],[-161,-203],[-347,178],[-304,-36],[-254,-163],[-157,71],[-338,-95],[-420,356],[-448,-25],[-111,-130],[-297,-128]],[[29788,29811],[-266,267],[-146,-35],[-213,52],[-113,450],[-148,430],[-316,271],[-320,353],[-423,670],[-52,293],[-734,359],[-517,217]],[[38773,16551],[-289,162],[-277,-44],[-193,147],[-94,-8],[-273,-453],[-307,399],[-433,240],[-147,343],[9,197],[-85,163],[-168,599],[-239,304],[-106,377],[-136,-11],[-208,114],[-191,-20],[-292,318],[-35,106],[-221,229],[103,298],[-60,168],[127,443],[13,310],[-209,255],[-51,279],[-103,92],[44,574],[103,303],[-100,173],[-269,27],[-233,583],[-166,253],[15,167],[-71,435],[-92,212],[91,440],[-82,147],[59,379]],[[42112,12148],[-49,410],[-240,455],[-171,120],[32,523],[-171,102],[-131,214],[-26,293],[-200,568],[-80,303],[-42,387],[-86,239],[-191,200],[-290,221],[-297,427],[-42,-430],[-129,-215],[-379,135],[-296,1],[-149,-84],[-91,-233],[-213,-67],[-168,522],[70,312]],[[30662,7911],[138,-88],[102,-223],[196,-274],[307,49],[322,-156],[227,26],[68,-252],[22,-310],[238,-106],[121,-123],[404,38],[107,121],[604,359],[92,109],[313,-408],[212,-134],[194,-34],[-1,-431],[161,-175],[64,-255],[209,-57],[125,102],[467,-422],[113,0],[394,-539],[234,86],[273,273],[18,89],[385,694],[4,357],[233,384],[187,-278],[159,-97],[191,15],[303,348],[266,70],[109,338],[251,58],[313,390],[154,249],[136,462],[127,125],[155,274],[26,308],[156,261],[135,-54],[209,146],[215,51],[140,-52],[68,303],[132,98],[269,-33],[120,-121],[287,-57],[207,238],[-27,594],[-105,360],[-67,467],[185,237],[164,378],[223,108],[416,351]],[[80812,69680],[-164,-439],[153,-346]],[[81461,77504],[-346,-309],[-99,-313],[-186,-321],[-221,-120],[-116,28],[-419,-133],[-199,-320],[162,-983],[196,-840],[-46,-332],[71,-366],[243,-484],[50,-261],[-20,-414],[-77,-204],[103,-42],[21,-180],[312,-452],[110,-406],[84,-24],[-154,-1000],[-118,-348]],[[82204,71843],[175,125],[155,348],[38,190],[-203,252],[244,380],[-69,346],[-213,309],[227,282],[66,236],[-77,352],[-105,53],[-398,-298],[-60,332],[38,116],[-35,337],[-56,-34],[-314,659],[-149,849],[31,479],[70,216],[-108,132]],[[80801,68895],[319,476],[157,132],[214,323],[135,29],[12,191],[297,307],[-159,434],[270,397],[6,211],[125,182],[27,266]],[[81214,64099],[334,-467],[46,-236],[110,-47],[164,-223],[168,-76],[183,27],[180,-216],[49,-521],[-53,-114],[43,-301],[-17,-333],[-68,-319],[33,-169],[-104,-217],[51,-216],[233,-243],[259,-118],[190,-287],[0,-112],[204,-493],[19,-270],[103,-163],[193,-587],[34,-476],[72,-245],[214,-191],[23,-228],[-61,-126],[28,-220],[190,-191],[121,-366],[91,-16]],[[87905,69414],[-171,-225],[-127,-32],[-190,197],[-189,-73],[-294,-17],[-99,-323],[-179,-236],[-9,-141],[-465,-607],[-286,-107],[-15,-156],[-566,-393],[-385,-357],[-120,-56],[-242,-259],[-638,-262],[-187,-220],[-171,23],[-156,-85],[-353,-36],[-263,-133],[-111,-171],[-61,-332],[-123,-161],[-117,-438],[-314,-177],[-212,-6],[-110,87],[-313,-165],[-225,-454]],[[89022,69147],[-32,61],[-341,-17],[-116,-56],[-316,99],[-312,180]],[[84246,56339],[245,292],[105,65],[-48,414],[83,257],[130,201],[-28,296],[48,209],[102,39],[368,471],[97,268],[-128,54],[35,269],[-96,102],[181,381],[-62,198],[226,153],[84,159],[175,146],[130,250],[114,75],[230,-122],[285,28],[279,123],[101,648],[308,75],[143,-136],[179,58],[-12,248],[-146,105],[217,343],[130,75],[-66,206],[-26,309],[37,128],[-255,417],[215,498],[413,223],[70,83],[446,-309],[234,-79],[64,292],[227,274],[127,221],[213,79],[22,128],[188,179],[72,149],[214,129],[241,55],[77,102],[221,100],[-13,138],[122,304],[-55,153],[59,268],[221,276],[-158,281],[-77,25],[-43,257],[42,208],[138,175],[-11,253],[-80,404],[-60,24],[-266,401],[-39,173],[-173,-224],[-179,50],[-264,300],[-230,-17],[-141,227],[-180,95],[-46,109]],[[78323,65248],[-53,-111],[269,-121],[263,12],[429,270],[173,-73],[118,278],[336,267],[135,-152],[227,222],[417,-180],[116,-219],[-10,-290],[58,-152],[162,-87],[-18,-383],[58,-281],[211,-149]],[[79452,66884],[-148,-324],[-85,-295],[-159,-232],[-429,-367],[-45,-118],[-263,-300]],[[80801,68895],[-349,-597],[-218,-158],[-268,-605],[-210,-280],[-161,-98],[-143,-273]],[[87905,69414],[-136,214],[-2,287],[-453,196],[-130,363],[-148,43],[66,126],[-160,82],[-72,377],[-73,-6],[-158,-262],[-269,-149],[-108,90],[-63,-225],[-181,-386],[-156,-120],[-143,101],[-307,47],[-244,-266],[-205,-296],[-658,-334],[-278,795],[-76,589],[-263,416],[-208,428],[-151,84],[-230,409],[-134,48],[-270,-332],[-91,-224],[7,-184],[-134,27],[-273,491]],[[76930,70218],[419,-263],[562,-719],[299,-236],[144,-204],[86,-306],[244,-340],[124,-264],[274,-228],[348,-641],[22,-133]],[[77550,71466],[-65,-255],[-238,-375],[-101,-11],[-215,-351],[-1,-256]],[[80812,69680],[-288,141],[-35,155],[-312,-11],[-461,703],[-158,-22],[-98,224],[17,315],[-149,187],[-174,-381],[-76,-25],[-299,177],[138,25],[118,276],[11,253],[-227,90],[-337,-81],[-501,-321],[-69,160],[-287,6],[-75,-85]],[[71575,76151],[6,156],[589,946],[229,201],[299,53],[354,129],[190,24],[452,-457],[366,-661],[-6,-197],[73,-207],[218,-280],[117,-60],[108,-345],[233,-551],[224,-257],[99,-2],[119,169],[270,230],[1639,-2166],[276,-709],[162,-301],[-42,-400]],[[68093,80135],[42,-80],[-23,-376],[301,-704],[127,-354],[8,-357],[472,-262],[60,-180],[137,22],[188,-165],[292,-364],[203,-33],[26,-475],[109,-432]],[[82844,83095],[-255,-24],[-103,304],[-264,175],[-38,271],[33,630],[-288,-62],[-362,134],[-164,-146],[-139,88],[-494,-5],[-545,406],[-174,-50],[-159,148],[-506,184],[-204,418],[-250,267],[-137,341],[-102,129],[-550,245],[-187,-80],[-377,109],[-102,316],[-392,-22],[-215,112],[-441,412],[-216,-224],[-242,-99],[-126,45],[-215,-77],[-51,-124],[-458,537],[-171,-15],[-253,102],[-178,-2],[-476,385],[-143,273],[-206,21],[-246,-63],[-167,126],[-167,-34],[-180,80],[-505,-330],[-155,-225],[-250,-151],[-184,94],[-231,-282],[-27,-189],[-131,-227],[-164,-500],[-125,-169],[-352,41],[-78,-110],[-240,-79],[-252,-205],[-117,-434],[-291,-291],[-10,-296],[147,-405],[140,-155],[-51,-205],[164,-273],[-12,-190],[86,-51],[140,-289],[-134,-381],[42,-292],[-44,-316],[-171,-439],[-174,-2],[-310,-293],[-77,-124],[-260,-191],[-84,85],[-241,-96],[-361,-28],[-51,-155],[-371,-403],[-109,-428],[2,-207]],[[81461,77504],[97,347],[-24,423],[-51,236],[29,453],[72,203],[170,242],[48,375],[-70,476],[55,150],[142,5],[80,154],[365,476],[204,209],[236,94],[-42,236],[80,374],[273,318],[-21,189],[-260,631]],[[78295,66071],[-53,-479],[81,-344]],[[76930,70218],[-225,-728],[460,-403],[118,-253],[55,14],[241,-363],[-35,-184],[-201,-163],[-13,-212],[233,-307],[280,-110],[123,-256],[269,-397],[-6,-232],[92,-366],[-26,-187]],[[87104,84270],[82,-452],[110,-164],[168,-86],[138,-223],[68,-323],[207,-281],[161,-127],[360,-623],[314,-258],[148,-71],[283,-590],[-15,-340],[122,-398],[583,608],[98,57],[110,-443],[201,-441],[429,214],[225,-167],[429,-34],[259,203],[335,87],[107,-173],[15,-321],[212,-364],[-29,-162],[125,-179],[1,-187],[195,-120],[-109,-209],[143,52],[117,-252],[164,-138],[-109,-362],[-425,-294],[-162,-23],[-143,-114],[-176,-3],[-176,-129],[6,-173],[-184,-154],[-218,253],[-172,-129],[-237,-316],[-42,-188],[-286,-323],[133,-243],[-18,-387],[49,-232],[-63,-252],[76,-257],[240,-460],[65,-423],[-262,-326],[-134,-292],[-264,-350],[-155,-138],[45,-248],[89,-131],[-30,-375],[-64,-169],[-279,-417],[143,-341]],[[90107,71369],[113,-199],[312,-76],[315,156],[243,71],[406,546],[133,81],[332,378],[194,430],[131,99],[328,506],[83,4],[120,532],[95,160],[636,627],[488,159],[151,-271],[258,2],[144,158],[-154,885],[204,324],[34,142],[-54,327],[176,215],[232,92],[-12,204],[-137,14],[-26,358],[-212,382],[60,280],[168,289],[85,302],[164,141],[24,163],[-45,428],[-142,402],[40,374],[142,-96],[215,54],[174,-223],[565,52],[194,248],[309,-260],[271,244],[186,58],[240,257],[164,14],[186,-106],[319,-95],[100,269],[391,1294],[228,51],[278,394],[130,387],[205,312],[-7,94],[288,339],[-33,57],[129,320],[203,123],[128,177],[-55,255],[-241,111],[-76,230],[-398,628],[-108,42],[-136,-201],[-185,-91],[-198,81],[-558,315],[-249,356],[-323,46],[-161,347],[-211,44],[-49,264],[-127,234],[13,160],[-115,306],[-100,616],[19,458],[-104,134],[-122,351],[-27,403],[-132,536],[-421,790],[29,276],[-169,415],[18,188],[-109,178],[72,219],[85,964],[76,189],[-160,326],[31,232],[133,105],[325,586],[58,335],[-15,383],[196,478],[9,1244],[93,123],[-77,66],[-76,463],[9,201],[-72,348],[86,160],[54,917],[-40,260],[73,163],[-90,95],[-134,441],[-1125,211],[-227,-870],[-11,-134],[-227,-204],[-405,-805],[-31,-183],[-230,-379],[-298,-112],[-99,24],[-73,-328],[-104,-209],[2,-478],[-44,-119],[39,-454],[109,-179],[-21,-617],[-99,-378],[-13,-217],[-157,-313],[-36,-338],[-186,-283],[24,-255],[-51,-213],[78,-271],[-23,-192],[64,-339],[-95,-239],[-58,-429],[242,-474],[-244,-594],[-168,-178],[-97,-212],[-248,-372],[20,-285],[-182,-202],[-274,-462],[-283,-213],[-143,-181],[-542,-162],[-180,50],[-342,-79],[-101,-90],[-234,-588],[12,-231],[-265,-349],[-212,-438],[-275,-189],[-206,-40],[-136,64],[-51,-119],[-328,-132],[-250,-632],[-244,-276],[-326,67],[-197,-145],[-81,-146],[-319,-92],[-47,-223],[-238,-292]],[[87104,84270],[-306,19],[-314,-138],[-251,-222],[-128,-36],[-157,75],[-174,-76],[-187,97],[-199,-120],[-167,60],[-193,-79],[-183,19],[-516,-156],[-325,-299],[-256,136],[-242,-114],[-307,-17],[-355,-324]],[[89022,69147],[139,94],[63,184],[154,124],[224,355],[-8,386],[235,439],[47,318],[168,136],[63,186]],[[34514,60274],[437,-228],[112,-182],[309,-322],[162,-228],[19,-133],[367,-212],[76,-167],[-78,-645],[25,-266],[118,-323],[-85,-159],[95,-519],[-37,-467],[122,323],[121,22],[448,-764],[-114,-90],[-18,-267],[-119,-184],[-225,-29],[382,-2594],[-37,-113],[200,-152],[45,-208],[-123,-124],[-27,-236],[-158,-45],[-116,-247],[24,-439],[-119,-81],[43,-151]],[[34515,61855],[111,-288],[40,-298],[-115,-276],[-109,-390],[72,-329]],[[40568,64766],[-183,220],[5,353],[-280,275],[-399,13],[-205,52],[-96,-56],[-153,166],[-68,193],[-307,-133],[-162,-338],[-188,-225],[-619,-51],[-111,-176],[-200,-25],[-137,-179],[-289,-123],[-194,-243],[-93,282],[-401,-441],[-246,-500],[-80,32],[-138,-181],[-39,-167],[-199,-314],[-143,22],[-255,-455],[-279,-198],[-83,-163],[-275,-95],[-236,-456]],[[38295,51387],[-30,69],[102,469],[-55,334],[110,382],[99,74],[112,896],[95,126],[-44,332],[52,293],[67,52],[-60,298],[117,235],[7,190],[188,287],[-23,199],[138,360],[200,300],[33,171],[237,536],[134,869],[-21,162],[129,459],[-107,623],[-211,445],[-101,387],[12,233],[-132,418],[-112,91],[-92,345],[-237,162],[-115,249],[9,147],[-161,181],[-138,288],[-158,223],[-137,69],[104,236],[787,790],[226,506],[336,346],[435,162],[264,266],[214,119]],[[37874,49541],[-216,227],[-78,377],[131,283],[285,461],[93,300],[207,104],[-1,94]],[[37109,49244],[328,176],[-20,86],[150,178],[307,-143]],[[36363,51044],[210,-212],[87,-188],[-7,-346],[61,-385],[-148,-257],[18,-205],[143,-178],[154,-81],[205,129],[23,-77]],[[43695,35696],[-340,-318],[-652,-177],[-139,25],[-231,177],[-529,-31],[-50,-233],[-403,-382],[-94,-204],[-113,313],[-49,371],[-132,654],[153,184],[-307,-107],[-248,-200],[-69,79],[-128,-272],[-104,-397],[-180,-116],[-109,-210],[6,-163],[-102,-372],[-7,-532],[-241,-695],[-271,-241],[-414,-155],[-112,-199],[-90,-358],[-236,-47]],[[49416,21985],[-92,230],[-66,508],[-117,195],[-58,671],[68,52],[238,577],[-51,143],[-218,267],[-350,111],[-78,79],[-57,349],[-87,199],[-297,112],[-90,282],[-25,435],[-251,556],[-167,130],[-138,-14],[-240,320],[-214,223],[207,823],[-30,234],[-202,228],[-27,347],[-102,111],[-112,349],[-317,360],[-123,11],[20,133],[-196,457],[-17,248],[-187,269],[-319,263],[-194,436],[9,173],[-85,203],[-10,378],[-330,516],[-151,643],[-172,192],[-208,563],[-113,136],[-111,423],[-205,381],[-259,199],[-197,210]],[[47242,16117],[95,174],[360,469],[111,92],[174,286],[11,184],[123,260],[340,200],[192,35],[181,117],[45,482],[-66,159],[56,545],[115,308],[77,790],[132,470],[72,41],[56,647],[100,609]],[[42112,12148],[200,-61],[116,51],[137,204],[4,304],[206,330],[328,-409],[184,-134],[229,163],[14,142],[233,240],[93,-11],[114,-249],[499,-477],[442,47],[180,-238],[249,251],[150,342],[77,418],[-65,75],[-61,645],[-67,116],[-33,427],[-77,379],[44,204],[166,309],[39,439],[261,349],[630,-47],[345,78],[94,107],[177,-50],[222,25]],[[38504,32090],[95,-296],[-57,-799],[82,-582],[-23,-279],[36,-267],[-42,-324],[99,-143],[-53,-219],[53,-381],[82,-227],[-113,-303],[90,-602],[61,-164],[-105,-444],[-173,-383],[-120,-73],[133,-321],[-24,-236],[390,-153],[-1,-849],[-53,-246],[30,-522],[-195,-428],[-6,-281],[-165,-281],[-42,-470],[65,-219],[180,-324],[263,-163],[-32,-768],[-152,-498],[34,-332],[-37,-433],[35,-98],[-65,-420],[94,-351],[-12,-309],[42,-214],[246,-184],[219,-334],[70,-701],[-36,-193],[-147,-77],[-228,-422],[-249,-226]],[[37768,41291],[-108,-110],[-353,-91],[-103,625],[-233,-149],[-503,-243],[-145,-271],[-58,-548],[-71,-280],[-49,-679],[-207,-547],[-434,-603],[-119,-296],[-398,-506],[-203,129]],[[38504,32090],[-84,329],[7,359],[93,212],[12,486],[42,326],[-80,403],[-25,433],[-344,582],[51,157],[-25,460],[-125,945],[42,492],[109,320],[133,199],[128,530],[338,308],[93,132],[-38,248],[-128,83],[-312,666],[-169,262],[-192,205],[-115,401],[30,161],[-177,502]],[[37738,41474],[30,-183]],[[43735,38475],[-83,-246],[-202,-158],[-322,-117],[-178,33],[-124,184],[-177,424],[-165,64],[-168,480],[13,216],[-75,155],[-123,534],[-344,99],[-300,487],[-462,256],[-694,442],[-319,249],[-70,125],[-158,32],[-384,-95],[-374,-153],[-385,-306],[-381,141],[-237,9],[-38,120],[-247,24]],[[43695,35696],[19,105],[201,167],[172,24],[2,159],[-211,303],[-59,220],[162,455],[-21,176],[64,211],[-115,38],[41,172],[-129,371],[-86,378]],[[37437,45527],[-98,177],[-80,305],[-146,-303],[-57,57],[-520,-340],[-175,-46],[-317,-417],[-355,-168],[80,-736],[-41,-455],[46,-487],[-100,-695],[-120,-393],[-59,-692],[-214,-804],[-252,-576]],[[37738,41474],[-66,117],[83,455],[-88,347],[5,382],[115,197],[19,258],[-89,402],[46,431],[-69,281],[18,161],[-137,35],[-65,303],[-133,174],[81,234],[-21,276]],[[43735,38475],[227,333],[17,361],[-27,618],[172,521],[-54,419],[100,408],[108,183],[301,306],[220,431],[-275,673],[-41,176],[23,346]],[[38403,47523],[-149,-195],[-432,-778],[-276,-894],[-109,-129]],[[44506,43250],[-281,96],[-52,88],[-212,17],[-58,-91],[-491,-352],[-336,477],[-689,1138],[-389,1074],[-190,102],[-482,68],[-636,446],[-319,496],[-57,228],[7,264],[-69,252],[-156,190],[-88,455],[-613,-179],[-214,-102],[-209,-178],[-341,-80],[-228,-136]],[[51833,47609],[139,200],[51,374],[250,365],[242,278],[-123,410],[320,541],[-59,246],[-1,285],[193,423],[99,72],[-47,1045],[-102,793],[54,354],[-93,281],[193,142],[200,226],[85,1]],[[51191,48693],[24,-441],[93,-202],[323,-357],[202,-84]],[[53679,55845],[-139,-85],[-278,-290],[-127,-214],[-241,-190],[-237,49],[-215,-46],[-80,66],[-148,-288],[-52,-450],[40,-98],[-73,-574],[13,-223],[-60,-328],[74,-149],[39,-471],[-14,-399],[73,-117],[12,-315],[-52,-431],[-96,-245],[-138,-852],[-221,-313],[-55,-153],[-264,-318],[-111,-611],[-138,-107]],[[53234,53645],[-59,112],[136,111],[-51,245],[112,490],[-45,428],[229,399],[94,28],[29,387]],[[50062,59084],[111,-425],[210,177],[278,8],[174,163],[224,119],[154,257],[84,3],[227,432],[455,389]],[[49749,62815],[-184,-336],[-4,-304],[215,-1],[-48,-555],[193,-325],[-201,-220],[120,-220],[115,-350],[45,-267],[-40,-328],[85,-107],[100,-431],[-83,-287]],[[52805,64764],[-199,82],[-381,28],[-277,-94],[-162,17],[-114,105],[-236,-321],[-294,-59],[-99,-154],[-29,-237],[-728,-701],[-291,-356],[-78,-152],[-168,-107]],[[51979,60207],[364,331],[337,442],[-82,226],[21,185],[109,222],[-45,157],[113,645],[-90,805],[-16,754],[81,98],[34,692]],[[54825,52160],[65,-103],[415,-1531],[-23,-73],[74,-471],[-53,-585],[-182,-597],[123,-446],[-2,-572],[86,-317],[8,-266],[-92,-120],[-22,-515],[25,-537],[-17,-471],[-94,-289],[-4,-186],[-125,-333],[-93,-386]],[[57113,53533],[-211,341],[6,137],[-111,393],[-274,712],[-260,272],[-307,-5],[-206,-144],[-645,-279],[-207,-146],[-162,8],[-52,-179],[-224,-124],[52,-235],[-62,-413],[244,-574],[70,-333],[16,-506],[45,-298]],[[57278,49693],[-178,320],[-189,248],[-51,269],[19,255],[-147,436],[-110,593],[14,176],[181,151],[217,786],[34,345],[64,-9],[-19,270]],[[58233,45496],[-159,139],[-146,335],[-160,491],[-260,153],[-347,26],[-177,119],[-67,144],[18,475],[223,99],[249,793],[139,199],[-19,262],[-198,622],[-51,340]],[[57766,43336],[-93,354],[47,371],[-28,398],[388,723],[87,64],[66,250]],[[57752,43298],[14,38]],[[54914,44362],[136,-137],[210,-85],[229,-260],[495,-259],[279,-40],[273,-173],[1216,-110]],[[47486,65750],[-71,-514],[-140,-26],[-11,-131],[-300,-375],[90,-438],[-40,-279]],[[49749,62815],[39,371],[-64,25],[-95,-381],[-163,-257],[-65,-297],[75,-305],[-53,-303],[-367,258],[19,262],[-56,439],[-85,265],[-222,119],[-109,140],[-236,106],[509,341],[-54,116],[211,344],[-215,456],[-179,275],[-273,327],[206,388],[-29,169],[-112,92],[-172,-51],[-225,105],[-184,-90],[-170,64],[-194,-43]],[[49943,58789],[-68,70],[-73,415],[260,-190]],[[47014,63987],[226,-362],[53,-172],[261,-284],[86,-405],[233,-84],[205,-366],[-17,-144],[145,-351],[-67,-383],[166,-380],[177,-129],[115,-267],[398,-110],[110,-355],[194,-320],[107,-29],[227,-407],[93,-420],[88,-188],[129,-42]],[[47770,56284],[-195,-645],[-7,-991],[123,-508],[134,-422],[28,-403],[135,-920]],[[49943,58789],[110,-210],[148,-91],[4,-288],[-129,-231],[19,-256],[-61,-134],[-71,-446],[-184,19],[-299,-50],[-670,-191],[-195,-139],[-845,-488]],[[54676,65551],[-87,-163],[-42,-334],[-187,-172],[-263,-321],[-491,-396],[-38,-158],[76,-298],[-99,-256],[-38,-306],[163,-505],[4,-258],[-106,-355],[-242,-382],[-25,-284],[33,-394],[-106,-422],[275,-571],[89,-4],[58,-191],[176,-94],[-79,-231],[-25,-700],[-94,-279],[-244,-520],[-227,-835],[-79,-124],[2,402],[-157,16],[-353,139],[-105,166],[-168,-131],[-225,235],[-194,120],[118,282],[231,304],[134,496],[30,295],[-159,60],[41,178],[-86,476],[-208,171]],[[55247,62896],[-273,540],[-111,324],[8,146],[-95,357],[44,206],[190,328],[-55,270],[-279,484]],[[54375,56487],[69,882],[69,357],[173,298],[-3,665],[20,789],[-85,318],[58,337],[-16,274],[80,348],[-176,953],[134,299],[306,326],[243,563]],[[53679,55845],[-77,268],[485,208],[288,166]],[[47988,52395],[234,93],[172,-11],[1230,-1888],[1,-319],[100,-454],[147,-201],[214,-417],[264,-152],[121,2],[542,-387],[178,32]],[[54790,69800],[-355,358],[-307,712],[-193,-35],[-41,90],[-427,222],[-228,219],[-1779,1065],[-640,373],[-255,247],[-397,323],[-96,-424],[-348,-456],[-225,-36],[-199,-137],[-72,31],[-97,-299],[97,-410],[14,-337],[-129,-409],[-297,-346],[-182,41],[-143,-276],[126,-292],[39,-297],[-197,-300],[-62,-296],[-304,155],[-295,231],[-118,376],[-150,-54],[-238,29],[-282,-293],[-385,-57],[-184,-239],[-88,109],[-392,38],[-152,-190],[-422,10],[-134,-79],[-159,24],[-53,-150],[-243,-81],[-91,-157],[47,-196],[-86,-73],[-205,-778],[308,-365],[584,-405],[187,-14],[302,-339],[183,-289]],[[54080,66176],[-198,324],[-23,163],[241,259],[224,317],[124,405],[236,535],[90,121],[183,599],[-44,169],[-111,87],[-39,276],[27,369]],[[52805,64764],[38,76],[578,135],[198,98],[166,178],[52,202],[-3,383],[56,163],[190,177]],[[46027,66344],[189,-528],[253,-256],[313,-128],[193,298],[407,108],[104,-88]],[[55228,31574],[-95,488],[-224,534],[-941,1436],[-188,470],[-39,500],[48,321],[174,579],[80,445],[29,356],[88,2239],[-64,418],[62,304],[-1,372],[114,702],[134,485],[-59,352],[90,503],[-26,308],[116,479],[37,444],[178,427],[173,626]],[[51833,47609],[118,-242],[-18,-196],[98,-208],[13,-323],[204,-444],[66,-1010],[-89,-205],[48,-472],[-51,-271],[71,-217],[-11,-430],[27,-705],[-53,-215],[80,-380],[-66,-203],[-148,-189],[68,-355],[-68,-209],[30,-280],[-47,-390],[-80,-233],[122,-305],[156,-120],[32,-179],[-107,-311],[330,-474],[176,-82],[188,-293],[65,-210],[-62,-322],[74,-244],[-95,-440],[-165,-280],[-37,-152],[-283,-240],[-29,-121],[186,-312],[40,-329],[127,-106],[136,-420],[-18,-384],[210,-703],[267,-372],[110,-50],[116,-329],[413,-1006],[455,-354],[287,-117],[330,-294],[179,-309]],[[54825,52160],[-122,18],[-137,792],[-177,392],[-59,341],[-474,-70],[-31,60],[-323,3],[-268,-51]],[[47530,52203],[458,192]],[[46264,56097],[99,-21],[18,-274],[-71,-389],[34,-733],[353,105],[119,-665],[293,50],[92,-442],[32,-349],[297,-1176]],[[45732,58313],[68,-192],[183,-62],[186,-224],[-87,-172],[67,-174],[1,-284],[147,-244],[14,-140],[-88,-362],[41,-362]],[[47192,60241],[-274,-663],[21,-518],[-196,-135],[-377,-74],[-175,-478],[-24,-158],[-238,130],[-55,-116],[-142,84]],[[47770,56284],[118,348],[0,300],[-116,-8],[-62,228],[7,255],[76,124],[181,692],[229,687],[121,254],[-13,237],[-159,272],[-263,333],[-93,345],[-141,78],[-419,-275],[-44,87]],[[47014,63987],[-421,-190],[-213,-177],[10,-238],[-53,-209],[-26,-884],[-66,-160],[177,-46],[46,-235],[173,1],[432,-137],[69,-404],[-207,-385],[282,-428],[-25,-254]],[[54676,65551],[-45,130],[-25,455],[-221,-191],[-183,88],[-122,143]],[[54375,56487],[609,34],[239,-145],[149,16],[132,260],[216,52],[594,-519],[529,-152],[317,-35]],[[57848,63010],[17,232],[-43,288],[-350,-162],[-499,-42],[-103,-73],[-315,31],[-202,247],[-119,274],[-216,-147],[-169,-315],[-126,-82],[-82,-219],[-179,-14],[-215,-132]],[[57160,55998],[-100,51],[93,204],[20,773],[-53,334],[-8,569],[153,537],[279,654],[-20,415],[50,484],[103,655],[122,381],[-66,310],[19,215],[104,125],[76,603],[-70,276],[-14,426]],[[57283,33483],[-86,181],[-270,381],[-187,399],[35,472],[65,254],[-228,192],[-70,197],[28,390],[200,507],[-113,269],[-84,500],[104,94],[-58,398],[87,341],[103,76],[76,227],[-5,356],[-132,291],[176,268],[-38,209],[-242,442],[-172,157],[19,281],[157,347],[29,1008],[-41,98],[103,546],[480,291],[194,-38],[272,375],[67,306]],[[55228,31574],[31,342],[213,558],[180,100],[359,-32],[229,179],[279,129],[130,-8],[154,130],[199,-95],[117,276],[110,87],[54,243]],[[57137,55313],[21,655]],[[57113,53533],[126,76],[-126,1135],[24,569]],[[57158,55968],[2,30]],[[18804,28839],[-111,73],[-507,-352],[-408,-177],[-179,-41],[-250,-394],[25,-700],[-352,-177]],[[17022,27071],[55,-115],[271,-101],[143,-151],[67,-635],[205,-483],[36,-309],[-29,-227],[-228,-431],[-136,-173],[-69,-318],[-198,-222],[-209,-314],[-217,-110],[-237,-899],[-159,-433],[25,-1214]],[[21892,40580],[-437,65],[-220,114],[-453,-104],[-1273,622],[-217,207],[-136,216],[-206,780]],[[22039,39918],[-147,662]],[[23139,37156],[-276,669],[-605,1296],[-219,797]],[[21738,35260],[4,66],[287,440],[279,302],[-106,206],[744,721],[193,161]],[[17391,32860],[187,-19],[576,242],[374,233],[125,-148],[1566,126],[1490,2031],[29,-65]],[[18091,39104],[92,-537],[14,-356],[295,-529],[59,-184],[-149,-397],[-126,-180],[-22,-197],[-165,-193],[-156,-519],[-324,-498],[43,-218],[-51,-692],[94,-172],[-31,-602],[-57,-61],[27,-268],[-100,-405],[-143,-236]],[[17825,42685],[125,-267],[-13,-337],[206,-307],[51,-443],[85,-122],[28,-360],[-34,-331],[72,-119],[-75,-757],[-98,-129],[-81,-409]],[[18587,42964],[-145,-23],[-250,-202],[-367,-54]],[[18950,42480],[-363,484]],[[28153,40538],[-257,-417],[-18,-281],[-154,-377],[-328,-289],[-82,-182],[-174,-49],[-185,-202],[73,-264],[204,-238],[61,54],[180,-334],[-35,-299],[116,-265],[293,-187],[106,-214],[28,-384],[131,-381],[141,-201],[97,-260],[-18,-193],[121,-371],[181,-348],[24,-334],[102,-233],[156,-199],[185,-580],[236,-304],[66,6],[68,-441],[-18,-186],[216,-470]],[[21066,47352],[-268,33],[-96,-138],[-45,-429],[-131,-397],[34,-371],[-30,-181],[54,-195],[-135,-68],[-135,-343],[-161,-209],[43,-86],[-173,-204],[-245,-462],[-137,-165],[-273,-175],[-122,-213],[-170,-25],[-138,-275],[-351,-485]],[[25447,39833],[253,124],[830,74]],[[22039,39918],[89,83],[324,-174],[249,63],[217,227],[32,106],[229,170],[434,199],[111,-113],[669,34],[259,118],[206,-125],[182,115],[42,-207],[365,-581]],[[18950,42480],[1172,-36],[1022,65],[108,-156],[225,-157],[257,-271],[92,-374],[-19,-174],[85,-797]],[[15017,31179],[107,-192],[120,-72],[221,76],[173,588],[74,144],[371,-285],[117,72],[163,-268],[49,-196],[94,217],[350,-276],[370,82],[106,-153],[-95,-185],[-210,-247],[-195,-395],[-40,-208],[-145,-323],[132,-238],[30,-280],[-102,-487],[-79,-207],[-139,-798],[-19,-436],[377,-171],[175,130]],[[15210,31410],[-193,-231]],[[16384,35044],[-70,-493],[-114,-155],[-299,-248],[-26,-341],[-228,-764],[-58,-576],[-58,-41],[-211,-531],[-110,-485]],[[17391,32860],[-80,137],[-53,428],[-874,1619]],[[22226,31995],[281,1051],[106,285],[-274,705],[-601,1224]],[[12845,28261],[9,-283],[281,-379],[-284,-559],[-130,113],[-132,-15],[-145,-206],[137,-241],[395,-120],[489,-352],[-67,-566],[22,-586],[356,-506],[-103,-112],[12,-252],[-81,-623],[101,81],[552,57],[247,-882],[191,-150],[225,-346],[152,-406],[141,-185],[139,-504],[142,-141],[95,-394],[90,-62]],[[15017,31179],[-240,-136],[-38,-193],[-229,-147],[-38,-325],[-167,280],[-168,-292],[-494,-601],[-89,48],[-77,-244],[-146,103],[-109,-262],[-12,-260],[-215,-670],[-150,-219]],[[25032,37925],[500,-652],[208,-465],[176,-292],[-18,-183],[100,-191],[38,-373],[79,-258],[175,-384],[-16,-293],[204,-410],[-141,-174],[24,-221],[178,-158],[136,57],[-135,-790]],[[25447,39833],[-241,-348],[-72,-654],[-113,-549],[-93,-227],[104,-130]],[[23139,37156],[503,281],[543,169],[229,-304],[618,623]],[[10265,24216],[108,50],[74,-212],[179,-1031],[488,-1411],[215,88],[262,-705],[240,-250],[117,-246],[210,-173],[16,-412],[85,-199],[65,-327],[-15,-351],[106,-365],[-60,-118],[80,-240],[187,-47],[255,-235],[140,-233],[306,-147],[297,280],[70,-204],[228,-301],[-23,-345],[130,-292],[-53,-275],[32,-328],[208,-64],[151,-307],[96,-68],[-11,-185],[150,-217]],[[12792,28250],[-236,-196],[-216,-274],[-221,-136],[-226,-15],[-138,-221],[-110,-381],[-271,-259],[-30,-338],[-119,-665],[-71,-272],[-149,-289],[-104,-55],[-171,-388],[-135,-69],[-330,-476]],[[12845,28261],[-53,-11]],[[2347,40606],[-127,-189],[-207,-185],[4,-189],[-103,-552],[-133,-94],[-197,-428],[-65,-2],[-244,-315],[-170,-359],[53,-402],[-61,-144],[-83,-569],[251,-807],[16,-436],[79,-240],[12,-439],[84,-291],[202,-133],[342,146],[250,-535],[140,-100],[70,-278],[124,60],[86,167],[588,92],[132,86],[236,-65],[195,105],[225,-124]],[[8072,37243],[-204,435],[-193,719],[-121,175],[-34,296],[-430,366],[-75,158],[-68,368],[-409,268],[-250,-28],[-80,115],[233,264],[163,350],[185,252],[10,281],[81,179],[-220,184],[-231,-35],[-100,-94],[-443,-129],[-152,-121],[-466,-11],[-60,-55],[-319,-20],[64,-306],[-126,-210],[-151,-86],[-159,-190],[-54,-176],[-141,-146],[-49,-194],[-245,77],[-67,143],[-248,176],[-48,129],[-150,2],[-84,-169],[-272,182],[-302,-165],[-69,220],[-299,274],[-142,-115]],[[4046,34386],[160,107],[296,441],[11,201],[155,90],[253,350],[304,-102],[179,-174],[238,-54],[68,93],[209,32],[202,-91],[182,15],[214,126],[86,431],[341,395],[133,407],[211,94],[261,364],[309,119],[214,13]],[[9776,49042],[225,464],[-138,-32],[-13,170],[-243,181],[-163,24],[59,174],[-359,-7],[-400,311],[-80,189],[-148,124],[-178,289],[-113,270],[-124,56],[-52,-163],[-175,136],[-103,-8],[115,372],[-150,482],[-169,-127],[-178,-229],[-119,-18],[56,159],[-21,296],[537,685],[302,316],[132,-293],[122,-505],[-89,-54],[77,-284],[176,-117],[173,113],[-44,-150],[67,-267],[186,-234],[195,32],[187,143],[35,171],[166,-88],[112,238],[94,-49],[-58,-204],[108,-312],[64,-364],[85,-188],[179,12],[10,132],[204,40],[237,131],[30,-237],[321,120],[38,-199],[247,158],[-159,869],[-150,330],[48,356],[236,365]],[[4859,50304],[307,-613],[189,-80],[336,175],[156,268],[235,209],[151,-17],[156,-159],[199,5],[46,127],[82,-149],[182,37],[155,-399],[169,-85],[45,-160],[161,-149],[246,56],[168,153],[-60,265],[270,298],[676,-367],[3,-154],[139,-19],[19,-125],[286,8],[-14,-138],[308,-51],[108,-155],[199,-43]],[[5159,54180],[-7,-227],[88,-269],[74,-57],[143,-352],[26,-387],[-239,-458],[-114,-305],[71,-957],[-175,-533],[-167,-331]],[[6746,54546],[-148,-185],[-237,-148],[-186,-271],[-186,-49],[-667,216],[-53,128],[-110,-57]],[[7109,55012],[147,-200],[99,-255],[-247,-211],[36,-52],[2,-542],[-43,-843],[-190,-374],[-86,-275],[1,-204],[-94,-338],[-445,24],[-130,67],[116,328],[45,-57],[143,603],[88,697],[64,258],[102,119],[98,337],[-69,452]],[[8191,57789],[237,-585],[296,-986],[-259,-192],[114,-376],[-552,-617],[-47,61],[-375,57],[-437,-64],[-59,-75]],[[9468,58405],[-493,-216],[-784,-400]],[[11173,52821],[-59,377],[-124,287],[-444,654],[-235,254],[-315,248],[-222,302],[-106,482],[5,359],[-87,526],[-57,539],[-72,402],[-19,393],[30,761]],[[8375,55200],[193,150],[153,-472],[-446,-514],[-97,651],[197,185]],[[12188,49982],[-287,421],[-452,835],[-98,247],[-178,1336]],[[10583,43740],[114,439],[389,1073],[299,215],[20,178],[112,109],[2,137],[130,12],[-43,653],[-86,180],[284,94],[-31,95],[117,173],[-110,88],[-21,309],[166,171],[-51,139],[121,334],[-268,60],[114,602],[129,161],[-70,255],[117,174],[-83,120],[200,302],[54,169]],[[10091,43473],[253,144],[141,-6],[98,129]],[[9776,49042],[162,-328],[-88,-256],[-229,-214],[82,-226],[-156,-294],[-82,-267],[209,-384],[172,161],[-57,-214],[-61,-542],[27,-329],[-106,-261],[132,-545],[-24,-210],[-113,-202],[79,-143],[-20,-602],[-60,-191],[208,-297],[240,-225]],[[4040,42891],[-153,222],[15,201],[-157,404],[-123,-31],[-244,475],[-243,235],[76,236],[416,683],[121,305],[46,325],[-288,368],[127,314],[-46,74],[-334,-78],[-303,92],[-87,-65]],[[2027,42451],[390,161],[276,159],[28,-130],[222,-345],[34,-283],[269,75],[240,254],[255,21],[278,366],[21,162]],[[2863,46651],[52,-285],[-3,-535],[-92,-226],[-215,-174],[-138,-471],[-109,-192],[-149,-121],[2,-240],[-115,-138],[-45,-361],[-221,-410],[-15,-166],[212,-881]],[[7109,55012],[-363,-466]],[[6526,62407],[213,681],[70,313],[20,446],[-34,575],[-63,412],[-227,406],[-374,361],[-292,553],[-427,613],[-265,598],[-183,322]],[[2999,62636],[229,-198],[49,-213],[175,-151],[197,-276],[115,69],[122,-56],[515,21],[518,-66],[262,-86],[155,-128],[674,501],[239,115],[277,239]],[[4964,67687],[-405,-1313],[-25,-246],[-270,-297],[-80,-352],[-77,-24],[61,-285],[-62,-348],[-129,-302],[-112,-1057],[-434,-114],[-176,-447],[-256,-266]],[[262,61347],[117,155],[184,50],[383,-85],[571,91],[258,266],[75,309],[170,11],[472,-198],[187,118],[-270,453],[167,445],[229,-109],[194,-217]],[[4964,67687],[4,11],[-1738,3305],[-220,320],[-947,-4120],[-130,-216],[11,-154],[-93,-404],[17,-269],[125,-273],[133,-82],[-56,-545],[-131,-288],[-269,-251],[-99,-349],[-243,-453],[-112,-109],[-370,-55],[-28,59],[-250,-68],[-85,-163],[-135,-20],[-40,-132],[-253,-345],[-55,-698],[85,-648],[177,-393]],[[4859,50304],[54,-512],[-203,-381],[-534,-437],[-185,-46],[-117,-415],[-43,-512],[-132,-186],[-32,-188],[-223,-423],[-229,-30],[-327,-223],[-25,-300]],[[10043,42679],[-5,349],[53,445]],[[4040,42891],[121,104],[133,553],[153,410],[80,370],[570,594],[22,59],[409,125],[451,-20],[168,-116],[354,91],[261,-97],[245,78],[278,160],[116,-96],[262,123],[286,-214],[163,-222],[333,-178],[118,-166],[271,-210],[323,-449],[192,-64],[508,-857],[186,-190]],[[8072,37243],[246,138],[437,413],[163,199],[110,246],[138,159],[23,172],[230,295],[117,39],[235,319],[400,122]],[[2027,42451],[109,-541],[32,-351],[179,-953]],[[10315,39440],[-80,164],[70,203],[-6,429],[-186,829],[12,141],[-162,324],[-98,692],[113,164],[65,293]],[[10171,39345],[144,95]],[[2861,57366],[99,-328],[224,-127],[214,-678],[71,-55],[-130,-452],[43,-174],[128,-172],[219,3],[92,-317],[191,-275],[250,-103],[31,-247],[132,-273],[245,13],[73,242],[161,35],[255,-278]],[[8191,57789],[-130,521],[-341,-220],[-222,129],[-333,348],[-56,-98],[-162,-4],[-479,-448],[-376,227],[-105,-15],[-610,95],[-219,-156],[-474,42],[-129,-161],[-816,-423],[-258,32],[-426,-169],[-194,-123]],[[262,61347],[136,-127],[302,-1018],[104,-152],[-19,-462],[123,-132],[323,29],[268,78],[-3,-205],[153,-288],[-95,-300],[89,-577],[131,-315],[341,145],[347,-333],[158,-284],[241,-40]],[[9468,58405],[-85,573],[-80,211],[-471,894],[-248,222],[-124,7],[-604,-124],[-197,9],[-161,84],[-211,246],[-225,614],[-228,514],[-211,248],[-101,317],[4,187]],[[77579,59107],[67,421],[88,36],[-118,409],[317,227],[-115,347],[-27,444],[-114,368],[-155,321],[-271,219],[-206,276],[-209,180],[-76,312],[-58,461],[-181,488],[-368,428]],[[76153,64044],[-44,-163],[-187,-112],[-237,-228],[-51,-132],[-279,-220],[149,-154],[178,-370],[101,-104],[57,-532],[399,-730],[357,-723],[109,-124],[96,-251],[196,-292],[183,-400],[26,-214],[373,-188]],[[73662,60699],[-300,328],[-274,548],[30,261],[-178,232],[42,335],[-171,344],[-33,303],[40,244],[-32,356],[121,364],[-292,-58],[-48,628],[25,359],[-290,-349]],[[80433,55743],[240,-19],[267,-161],[19,-104],[149,-38],[179,-261],[349,-181],[226,136],[183,-41],[93,62],[297,-4],[-6,94],[232,-44],[264,245],[146,200],[151,47],[91,126],[256,152],[210,-162],[467,549]],[[77579,59107],[-28,-61]],[[76006,64447],[147,-403]],[[78295,66071],[-230,-191],[-186,-11],[-161,-142],[-106,101],[-116,262],[-230,12],[-86,-183],[-64,-357],[-233,-285],[-49,-261],[-374,-239],[-62,90],[-110,-383],[-128,-148],[-154,111]],[[75403,64059],[-67,501],[-274,611],[170,583],[53,271],[13,383],[105,682],[149,318],[-26,167],[44,365],[143,89],[166,247],[-611,1171]],[[73742,60969],[81,156],[45,281],[333,580],[217,586],[109,57],[-241,422],[258,-255],[114,274],[239,384],[23,244],[171,-172],[54,91],[-113,261],[179,173],[192,8]],[[62889,56194],[449,214],[411,320],[182,82],[159,-65],[390,116],[14,82],[483,111],[114,184],[53,578]],[[63573,62292],[107,-113],[-125,-135],[-137,-270],[-13,-394],[-125,-186],[-90,-383],[-145,-213],[75,-296],[-180,-250],[-154,-383],[-599,-622],[-264,-435],[-319,-391],[-83,-194],[118,-999],[310,-85],[27,-251],[218,-86],[217,28],[271,-389],[207,-51]],[[65143,57985],[-310,120],[102,184],[52,509],[-17,733],[-98,611],[-104,184],[-180,543],[-135,200],[-204,737],[37,206],[-22,374],[-101,116],[-386,-90],[-204,-120]],[[63314,66882],[-113,462],[151,208],[4,292],[314,413],[254,223],[22,194],[225,149],[179,31],[147,292],[145,-73],[285,116],[99,222],[94,11],[88,189],[165,154],[198,315],[294,118]],[[62115,66646],[282,-206],[216,116],[97,-26],[337,262],[267,90]],[[58505,72715],[306,-598],[50,-343],[324,-497],[346,-293],[329,-194],[34,-82],[-148,-533],[117,-465],[408,-741],[96,-72],[146,-325],[177,-185],[276,-464],[124,-76],[197,-344],[118,-78],[110,-214],[276,-343],[324,-222]],[[68093,80135],[-300,-122],[-236,-277],[83,-240],[-120,-202],[-351,-1],[-328,-624],[-256,35],[-262,-171],[-269,-391],[-138,-22],[-261,131],[-220,-310],[-190,-70],[-319,-208],[-493,-110],[-366,59],[-781,-140],[-126,191],[-206,-38],[-441,-528],[-501,-424],[-152,-293],[-25,-192],[-1509,-1019],[-76,-26],[-145,-324],[-199,-307],[-161,-66],[-215,-226],[-85,-301],[-298,-295],[-83,-451],[-337,-106],[-222,-352]],[[63241,51697],[-65,450],[-112,-47],[-394,104],[-94,382],[-142,174],[30,225],[-118,158],[139,7],[26,160],[-102,19],[-5,230]],[[59957,48159],[213,69],[433,274],[321,-127],[148,15],[497,655],[240,376],[48,266],[206,88],[84,109],[27,278],[180,33],[241,145],[63,220],[352,270],[347,391],[22,146],[-138,330]],[[60411,55272],[128,-516],[-60,-67],[13,-298],[155,-162],[96,-468],[6,-338],[72,-430],[-12,-204],[129,-412],[-38,-168],[-129,-140],[-132,-428],[-48,-407],[-210,-574],[-55,-430],[-22,-582],[-78,-344],[-185,-272],[7,-327],[-91,-546]],[[62404,53559],[-131,15],[-1,200],[-140,-19],[-323,101],[42,157],[-395,167],[-34,-90],[-173,145],[-208,321],[90,187],[52,404],[-182,23],[-581,353],[-9,-251]],[[57278,49693],[99,127],[324,146],[221,304],[317,158],[560,1182],[87,291],[278,281],[210,518],[204,353],[77,373],[222,228],[67,315],[126,195],[4,402],[-115,305]],[[59959,54871],[-596,199],[-710,367],[-494,-12],[-79,85],[-240,19],[-426,-103],[-277,-113]],[[56615,70878],[-56,-195],[-217,-153],[-558,-143],[-225,-377],[-140,-400],[-414,-117],[-215,307]],[[59970,64159],[-74,-11],[-178,208],[-541,374],[-274,-34],[-195,-210],[-274,-164],[-55,231],[-202,357],[-52,290],[38,340],[-165,200],[-161,-13],[-32,274],[182,695],[130,225],[199,126],[-315,537],[-274,258],[-389,229],[-158,288],[-206,45],[221,234],[90,176],[31,529],[-63,242],[-345,448],[-293,845]],[[59648,62826],[103,242],[135,90],[-36,275],[97,175],[48,447],[-25,104]],[[57848,63010],[235,26],[201,152],[127,-8],[240,121],[263,-79],[187,90],[218,-79],[329,-407]],[[59970,64159],[177,585],[291,48],[94,104]],[[57092,71321],[-200,-342],[-277,-101]],[[60532,64896],[-114,366],[34,225],[-164,124],[-133,-96],[-64,253],[-400,509],[-114,273],[-15,203],[-160,428],[-19,199],[-129,472],[-153,-86],[-154,224],[-83,309],[-226,491],[-137,90],[-81,288],[13,323],[-134,342],[-229,185],[-381,721],[-597,582]],[[60015,55491],[-52,423],[-90,171],[152,987],[49,211],[46,512],[124,233],[182,497],[123,649],[126,152],[99,383],[144,356],[111,85],[82,577],[143,293],[74,489],[-44,261],[60,720],[-33,218],[82,320],[48,425],[-74,106],[-256,814],[116,137],[-226,608]],[[59959,54871],[114,449],[-58,171]],[[59648,62826],[-121,-296],[-41,-366],[80,-463],[-162,-977],[13,-732],[76,-399],[-13,-261],[-162,-533],[-206,-283],[-182,-376],[-259,-681],[-99,-354],[101,12],[-25,-358],[170,-9],[-2,-584],[-696,186],[-274,48],[-226,-96],[-124,-371],[-144,-54],[-194,89]],[[61001,65118],[-140,-28],[-138,-169],[-191,-25]],[[62115,66646],[-112,-107],[-191,-369],[-182,-239],[-178,-138],[-131,54],[-130,-129],[-190,-600]],[[63573,62292],[-65,404],[99,225],[-2,335],[140,410],[35,594],[79,183],[-60,281],[4,343],[-57,302],[25,323],[-48,509],[-87,160],[-170,135],[-152,386]],[[62803,55612],[86,582]],[[62546,53635],[-352,404],[8,270],[300,-89],[60,338],[130,402],[111,652]],[[62404,53559],[142,76]],[[60015,55491],[170,77],[140,-37],[86,-259]],[[60088,47205],[-123,534],[-8,420]],[[58233,45496],[519,-304],[218,-23],[281,201],[170,24],[239,315],[46,571],[17,721],[365,204]],[[58505,72715],[-144,58],[-87,-260],[-214,-252],[-266,-119],[-80,-237],[-622,-584]],[[76006,64447],[-40,79],[-88,-267],[-89,10],[-386,-210]],[[15304,37607],[429,221],[19,324],[388,5],[785,429],[10,322],[108,212],[56,308],[366,180],[113,-198],[141,-54],[372,-252]],[[15313,40605],[-131,-171],[-112,-268],[-85,-486],[35,-247],[293,-1432],[-9,-394]],[[15331,41171],[81,-444],[-99,-122]],[[17825,42685],[-249,214],[-428,-194],[-179,-212],[-82,-181],[-197,-71],[-211,-200],[-46,-140],[-136,-36],[-328,-317],[-162,-23],[-29,-108],[-195,-128],[-204,-9],[-48,-109]],[[15293,37222],[12,-598],[199,-473],[521,-537],[359,-570]],[[15304,37607],[-11,-385]],[[15313,40605],[-209,175],[-452,60],[-326,-113],[-301,3],[-259,-387],[-283,-2],[-68,-103],[-476,-315],[-184,-20],[-42,-323],[-782,-848],[-329,-46],[-227,63],[-114,-39],[-344,33],[-419,280],[-266,79],[-61,243]],[[13833,36926],[435,-19],[322,113],[413,-64],[290,266]],[[7453,33337],[365,69],[178,125],[369,65],[130,65],[299,-79],[110,112],[372,-320],[120,-18],[175,-154],[558,-17],[273,-193],[180,-49],[277,-218],[163,131],[281,96],[275,-37],[140,184],[157,364],[23,171],[166,287],[268,218],[1,157],[-137,129],[-101,437],[2,306],[134,219],[38,746],[-89,344],[231,10],[-13,154],[123,-55],[245,11],[78,164],[140,26],[137,-88],[538,133],[174,94]],[[4046,34386],[-34,-135],[170,-320],[222,-142],[252,-94],[136,33],[293,-119],[464,-26],[112,-70],[223,100],[264,-114],[52,-158],[221,-119],[364,209],[112,119],[272,-216],[145,99],[139,-96]],[[6944,27070],[-179,-12],[-299,-386],[-203,-153],[-78,-502],[-114,-153],[-121,-735],[-131,-410],[-11,-365],[-61,-97],[215,-181],[20,-275],[123,-146],[325,-249],[199,-30],[84,-191],[182,2],[26,355],[149,280],[548,152],[115,113],[189,24],[151,235],[-18,219],[147,123],[152,419],[174,138],[-4,108],[349,635],[237,-75],[318,163],[200,-226],[37,-154],[-102,-42],[24,-348],[-100,-155],[-22,-227],[51,-179],[101,-6],[118,-308],[271,-285],[259,70]],[[12792,28250],[60,281],[44,485],[-12,308],[-247,501],[-106,-32],[-246,184],[-443,466],[-59,14],[-187,-240],[-364,-146],[220,-386],[181,-230],[-194,-226],[-324,-459],[-15,-165],[100,-325],[-140,-263],[-234,-54],[-204,81],[-321,249],[-353,63],[-277,-254],[-449,-202],[-293,-18],[-373,-601],[-156,145],[-210,325],[-64,-301],[-463,-414],[-106,-286],[-167,-83],[-291,334],[-155,69]],[[13545,45996],[8,740],[-47,234],[-105,173],[-190,163],[-137,453],[-246,471],[-78,294],[-38,641],[-146,378],[-378,439]],[[13384,45838],[161,158]],[[10583,43740],[280,605],[382,507],[337,695],[282,-45],[380,-7],[54,-166],[264,345],[160,85],[94,151],[260,-134],[94,128],[156,55],[58,-121]],[[13384,45838],[39,-233],[149,-23],[-48,-307],[-190,-204],[-107,-258],[-100,-560],[-5,-431],[-187,-366],[-440,-450],[-38,-215],[33,-218],[-49,-824],[-136,-243],[-491,-291],[-72,-331],[-180,-314],[-274,-78],[-232,-252],[-283,-596],[124,-249],[-452,-6],[-130,51]],[[15331,41171],[-125,442],[-116,158],[-204,662],[-315,571],[-235,254],[-179,120],[-94,187],[-9,362],[-201,1484],[-230,274],[-78,311]],[[15210,31410],[-444,592],[214,304],[155,352],[175,-15],[218,868],[91,204],[-183,348],[-223,171],[-91,311],[-317,-10],[-53,424],[148,256],[54,237],[-322,166],[-130,196],[-408,362],[-245,543],[-16,207]],[[7453,33337],[-109,-200],[-122,-620],[-126,-288],[-60,-288],[31,-328],[115,-172],[-136,-281],[-13,-210],[-172,-360],[-144,-156],[-103,-410],[-222,-269],[148,-269],[137,-420],[72,-77],[25,-267],[168,-235],[-78,-557],[-124,-96],[-3,-161],[114,-240],[93,-363]],[[44474,52314],[-499,-533],[-466,-382],[-202,-230],[-880,-391],[-815,-638]],[[46013,50741],[-329,173],[-312,390],[-176,427],[-133,39],[-252,-117],[-299,491],[-38,170]],[[44607,44726],[469,370],[659,858],[445,535],[244,382],[122,773],[-42,664],[25,300],[129,335],[-119,449],[147,143],[-38,254],[-218,166],[-417,786]],[[41612,50140],[160,-296],[275,-317],[204,140],[585,-605],[126,-174],[138,-616],[383,-971],[-51,-496],[103,-325],[-12,-248],[69,-140],[-5,-283],[122,-317],[898,-766]],[[46133,52676],[-392,584],[-612,-272],[-655,-674]],[[46013,50741],[-393,428],[-103,516],[92,82],[6,335],[191,287],[327,287]],[[38246,47931],[157,-408]],[[38592,48411],[-346,-480]],[[41612,50140],[-710,-363],[-372,-152],[-528,-165],[-153,-108],[-303,-110],[-510,-650],[-444,-181]],[[44506,43250],[153,153],[73,396],[-132,541],[71,306],[-64,80]],[[38295,51387],[227,147],[61,-154],[-70,-639],[35,-305]],[[42017,64054],[-101,226],[8,543],[-38,285],[-188,625],[-118,140],[-359,-205],[3,-259],[-129,-157],[-82,-273],[-357,-8],[-88,-205]],[[41912,60997],[201,288],[-9,86],[163,229],[-1,164],[-220,355],[-70,215],[-321,491],[113,657],[98,393],[151,179]],[[38548,50436],[223,664],[-33,344],[138,226],[-161,37],[120,406],[5,283],[255,563],[285,204],[172,212],[4,206],[163,33],[-24,319],[-89,202],[72,373],[-29,317],[85,144],[-22,256],[40,375],[299,122],[133,316],[-72,246],[145,298],[317,150],[-113,241],[-26,279],[-161,174],[240,568],[-13,705],[94,221],[255,184],[232,341],[326,579],[438,951],[66,22]],[[38548,50436],[442,-333],[507,424]],[[41217,51924],[75,317],[0,515],[44,178],[-484,-114],[-335,1397],[-106,273],[95,90],[-114,224],[407,135],[-7,233],[62,304],[132,173],[-134,689],[324,100],[-39,344],[-8,475],[-65,333],[130,130],[175,-17],[149,-125],[180,61],[99,129],[-20,220],[402,228],[-188,234],[-82,273],[-105,63],[-46,600],[-261,239],[103,292],[338,651],[48,149],[-74,280]],[[39497,50527],[370,250],[436,366],[-12,104],[285,158],[157,-45],[113,286],[207,224],[164,54]],[[38592,48411],[1126,1582],[-221,534]],[[37874,49541],[372,-1610]],[[43874,54380],[90,-115],[-162,-198],[-84,-600],[-264,-275],[-118,54],[-287,-295],[-141,-212],[-353,-327],[-131,6],[-430,-269],[-138,-146],[-320,-138],[-113,-111],[-241,-27],[35,197]],[[46264,56097],[-222,-239],[-129,-318],[-232,-362],[-278,-57],[-112,70],[-6,279],[-68,-286],[-125,-149],[-436,93],[-354,-96],[-317,-346],[-45,-263],[-66,-43]],[[46133,52676],[223,-253],[39,-183],[193,-323],[192,-65],[150,44],[204,195],[396,112]],[[54021,25822],[-35,238],[68,400],[91,217],[181,135],[280,621],[122,551],[169,299],[29,577],[51,253],[186,306],[-8,82],[325,642],[60,258],[-79,287],[-179,447],[-54,439]],[[54017,25761],[4,61]],[[49416,21985],[382,145],[103,-8],[140,-156],[84,-285],[136,-37],[160,-252],[96,-279],[213,289],[178,87],[186,-58],[269,303],[281,68],[146,318],[244,86],[171,147],[257,-54],[286,228],[119,154],[316,253],[114,-30],[-64,704],[97,545],[273,275],[89,190],[1,230],[96,518],[228,395]],[[43874,54380],[-66,52],[0,271],[-78,71],[30,176],[-107,154],[38,259],[-202,272],[247,310],[315,276],[59,126],[222,207],[60,-44],[225,271],[-63,200],[-12,305],[72,230],[-215,198],[129,11],[267,-94],[70,129],[205,-55],[342,0],[174,204],[-6,279],[152,125]],[[46027,66344],[-820,-612],[-86,-172],[-72,-317],[31,-294],[-65,-78],[-514,-199],[-132,-127],[-362,35],[-471,156],[-328,-41],[-87,-154],[12,-165],[-174,-214],[-27,-140],[-199,-76],[-254,266],[-253,-210],[-209,52]],[[35211,50670],[226,314],[221,166],[-40,-138],[118,-67],[336,146],[191,38],[100,-85]],[[34514,60274],[-84,-274],[-44,-420],[83,-198],[-111,-275],[92,-514],[-147,-436],[54,-402],[100,-112],[-121,-804],[-63,-276],[63,-202],[-179,-486],[-133,-591],[36,-164],[-62,-441],[480,-1788],[150,-138],[147,-252],[175,-102],[91,-179],[8,-434],[102,-223],[-26,-372],[89,-202],[-3,-319]],[[34797,48347],[133,-192],[635,241],[301,207],[222,326],[453,129],[235,-13],[333,199]],[[35211,50670],[-17,-262],[72,-279],[-250,-583],[-68,-522],[-60,-65],[-122,-404],[31,-208]],[[34515,61855],[-237,-297],[-233,36],[-226,-116],[-258,-227],[-273,-165],[-261,-92],[-118,21],[-312,-213],[-401,-94],[-247,-8],[-296,581],[11,101],[-148,349],[127,448],[-103,388],[117,147],[39,244],[98,164],[-9,537],[23,423],[-145,535],[-660,-1088],[-208,-111],[-293,199],[-145,-178],[-1511,-931],[-114,-445],[71,-309],[-21,-198],[71,-155],[-90,-225],[38,-168],[-79,-262],[61,-147],[-9,-359],[93,-182],[-54,-152],[-156,-138],[-255,-588],[-164,-205],[-109,32],[-221,-278],[-307,-109],[-229,15],[-285,-94],[-431,201],[-211,149],[-1223,-2025]],[[31737,46825],[243,273],[303,87],[118,106],[334,-24],[300,-233],[650,334],[153,180],[130,-15],[206,199],[-58,122],[223,204],[181,312],[115,77],[162,-100]],[[33493,43336],[100,-500],[-14,-270],[117,-388],[-4,-131],[143,-168]],[[62803,55612],[398,-105],[627,80],[16,107],[253,-70],[825,-17]],[[64922,55607],[110,341]],[[63971,39471],[-62,-294],[162,-588],[-105,-550],[54,-306],[-103,-490],[223,-588],[287,-106],[196,-625],[274,-464],[-7,-305],[159,-333],[152,-130]],[[64756,43743],[-42,-98],[68,-483],[-68,-332],[-2,-338],[65,-225],[-34,-158],[17,-416],[-143,-268],[5,-362],[-81,-313],[-320,-266],[-77,-184],[74,-337],[-247,-492]],[[65303,44797],[-159,-191],[-87,-325],[2,-456],[-90,-208],[-213,126]],[[68816,42748],[-150,-175],[-279,-124],[-508,49],[-213,-51],[-172,90],[-198,447],[-296,39],[-109,149],[-135,0],[-146,266],[-150,147],[-418,111],[-228,265],[-88,204],[-221,324],[-52,177],[-150,131]],[[71878,41061],[-661,578],[-482,315],[-235,2],[-149,227],[-488,14],[-222,321],[-33,172],[-306,-72],[-226,67],[-227,-70],[-33,133]],[[65201,34692],[111,168],[21,326],[234,302],[103,360],[-52,185],[226,493],[117,128],[53,197],[494,156],[621,344],[261,403],[230,55],[128,124],[-181,326],[-221,278],[-161,328],[429,182],[171,407],[262,329],[228,35],[384,-38],[235,230],[359,-9],[296,-306],[368,130],[332,298],[122,155],[461,276],[223,41],[448,-96],[56,-83],[190,-1],[198,-152]],[[57766,43336],[313,-89],[134,-169],[225,-126],[223,-37],[218,69],[130,142],[186,-69],[255,44],[282,240],[255,27],[9,544],[-94,336],[107,-11],[286,112],[705,107],[133,-106],[250,-370],[213,-115],[138,13],[86,-211],[159,-145]],[[62967,44987],[-130,144],[-130,264],[-51,227],[-116,202],[-291,332],[-153,79],[-111,-120],[-156,227],[-181,-167],[-181,47],[-171,828],[-267,-70],[-299,14],[-165,-186],[-190,77],[-287,320]],[[61979,43522],[321,520],[163,105],[147,257],[117,77],[240,506]],[[63236,45309],[-269,-322]],[[64756,43743],[-275,172],[-369,667],[-261,262],[-126,67],[-489,398]],[[61979,43522],[-72,-210],[-338,-467],[-71,-248],[261,-234],[-111,-428],[367,-329],[78,-158],[-52,-223],[59,-241],[205,-67],[159,-217],[42,-261],[100,-186],[193,-197],[204,-48],[206,-245],[598,-172],[164,-120]],[[64922,55607],[316,-76],[339,-212],[552,-463],[217,-36],[386,72],[-16,124],[305,107]],[[54021,25822],[411,272],[517,54],[417,-110],[139,31],[181,253],[255,496],[210,219],[265,143],[368,65],[280,-51],[173,31],[239,135],[115,180],[87,-11],[371,230],[177,4],[250,98],[355,7],[94,-56],[260,29],[34,492],[259,-22],[234,-138],[115,20],[138,-177],[418,202],[187,-228],[11,-104],[272,-250],[258,-546],[150,-135],[273,34],[358,-57],[217,82],[265,183],[6,258],[122,-45],[114,85],[310,20],[170,137],[292,355],[478,206]],[[64256,31417],[-211,241],[-388,189],[-65,339],[-126,193],[-152,352],[-250,-270],[-308,-30],[-305,-79],[-260,26],[-248,94],[-404,-274],[-371,-323],[-440,-54],[-195,168],[-215,297],[-738,52],[6,228],[156,343],[-140,-29],[-345,200],[-585,-428],[-202,-3],[-499,348],[-316,364],[-372,122]],[[63866,28213],[132,463],[10,230],[-48,620],[117,219],[125,85],[184,328],[75,230],[69,469],[-274,560]],[[68696,31342],[96,-332],[262,-384],[-143,-167],[19,-124],[-225,-134],[-26,-407],[101,-284],[274,-495],[-441,-618],[-60,-225],[-351,-628],[-16,-287],[-68,-74],[-51,-477],[-76,-48],[-86,-333],[-222,-463],[-205,-167],[-324,22],[-270,-264],[-89,-286],[-128,-225],[-116,-347],[-339,-470],[-123,-567]],[[72961,33838],[-132,-14],[-359,-317],[-230,-126],[-301,-296],[-280,-146],[-399,-342],[-225,-338],[-40,-167],[-201,-74],[-181,-176],[-1144,-242],[-554,-134],[-45,47],[-174,-171]],[[66945,17418],[448,-57],[161,-68],[283,155],[336,-9],[187,-128],[295,135],[394,75],[497,-20],[331,-154],[321,140],[99,-28],[465,249],[223,63],[522,-383],[187,-50],[308,574],[-21,218],[129,187],[66,300],[133,264],[83,501],[316,-102],[353,79],[50,448],[-61,311],[-91,101],[99,308],[114,111],[182,317],[-198,672],[-138,138],[242,286],[243,534],[174,216],[287,210],[243,115],[178,227],[-73,299],[-93,156],[-112,401],[-6,281],[-251,751],[-83,437],[-62,69],[38,571],[-162,144],[69,403],[-37,284],[239,661],[126,113],[70,354],[26,518],[-49,285],[92,355],[159,355],[-13,534],[60,165]],[[65459,20530],[86,-95],[113,-323],[229,-426],[147,-43],[233,-249],[281,51],[145,-35],[115,-490],[-74,-192],[82,-263],[-28,-500],[157,-547]],[[66089,23558],[-105,-220],[-164,-493],[-7,-125],[-202,-182],[-55,-354],[7,-599],[-37,-329],[23,-312],[-90,-414]],[[68451,33352],[-111,831],[-93,304],[140,21],[-172,520],[70,355],[178,276],[10,239],[455,-26],[1314,904],[251,5],[262,369],[171,397],[226,263],[50,257],[180,115],[170,1],[121,162],[157,82],[198,-57],[162,102],[21,109],[213,295]],[[65167,32886],[135,164],[329,33],[356,378],[260,-189],[410,-197],[130,-320],[181,-177],[717,507],[237,140],[378,46],[151,81]],[[65201,34692],[42,-85],[-15,-331],[-110,-296],[83,-323],[-27,-200],[30,-325],[-37,-246]],[[63866,28213],[125,-303],[33,-341],[335,-449],[66,-171],[-20,-437],[-130,-168],[21,-221],[-30,-466],[189,-495],[160,-197],[41,-157],[249,-264],[-4,-385],[160,-203],[299,-11],[255,-288],[258,-96],[216,-3]],[[65167,32886],[-170,-261],[4,-124],[-203,-175],[-38,-123],[-357,-420],[-147,-366]],[[68696,31342],[-63,511],[48,300],[-41,299],[-168,442],[-21,458]],[[65079,50018],[-526,-115],[-467,84]],[[67278,47109],[-272,89],[23,285],[-208,2],[10,279],[-540,306],[-30,347],[-177,58],[-507,54],[-95,130],[13,202],[-211,521],[-326,-37],[11,197],[94,186],[16,290]],[[65303,44797],[-148,636],[-82,119],[-74,350],[-144,238],[-166,516],[78,378],[-71,166],[85,97],[278,-58],[106,-103],[246,-80],[276,-272],[273,-78],[323,102],[103,155],[42,323],[363,-246],[91,-266],[265,-268],[143,-47],[59,146],[-97,309],[26,195]],[[64086,49987],[4,-279],[148,-538],[18,-619],[74,3],[-67,-422],[163,-502],[-3,-195],[-139,-197],[-227,-558],[-102,-135],[-255,-86],[-125,-332],[-121,2],[268,-277],[-192,-278],[-294,-265]],[[68816,42748],[-278,287],[-40,385],[97,827],[-13,158],[-204,289],[78,298],[273,422],[-95,443],[-308,191],[-411,407],[-183,343],[-225,-2],[-229,313]],[[54017,25761],[196,-575],[246,-321],[356,63],[253,372],[327,-177],[521,-649],[289,-99],[144,145],[157,45],[148,-106],[249,-5],[160,237],[191,45],[175,-84],[139,-326],[577,-354],[246,24],[342,-141],[553,-537],[428,264],[119,-79],[129,48],[175,200],[326,-495],[216,-188],[32,-441],[-42,-55],[64,-417],[255,-493],[147,-74],[135,-311],[74,-280],[350,-266],[194,-34],[242,59],[87,-160],[341,-397],[231,-189],[113,9],[162,-121],[117,-196],[117,124],[480,-25],[57,210],[247,-16],[161,-70],[406,188],[393,312],[417,105]],[[64086,49987],[-139,95],[-145,797],[-265,287],[-130,367],[72,35],[-238,129]],[[65185,51676],[77,842],[-76,515],[196,141],[185,-148],[192,-58],[298,148],[200,189],[-77,381],[167,41],[36,-240],[185,-252],[140,-53],[357,-376],[143,54],[228,-19],[248,98],[430,331],[28,82]],[[62546,53635],[331,11],[188,-59],[27,-201],[180,-42],[143,161],[360,-16],[296,-99],[83,121],[285,-117],[133,120],[190,-23],[47,-320],[213,-507],[83,-508],[-6,-171],[86,-309]],[[65185,51676],[-57,-425],[-118,-333],[-13,-559],[82,-341]],[[47242,16117],[214,-177],[218,-1017],[-57,-259],[131,-436],[324,-230],[261,42],[375,-90],[411,-18],[215,-72],[288,265],[109,-21],[103,132],[464,-173],[200,-4],[424,-107],[136,10],[314,197],[276,296],[246,32],[77,193],[172,100],[375,-118],[93,-190],[144,-39],[151,-510],[110,-51],[124,-442],[136,-88],[76,-781],[160,-229],[179,-55],[177,-188],[214,-68],[319,59],[164,-55],[81,-219],[149,-130],[178,-261],[159,-38],[92,-161],[-75,-395],[30,-402],[-106,-844],[61,-177],[153,-28],[110,-432],[-6,-196],[210,-56],[160,-444],[203,-89],[697,60],[119,449],[149,275],[286,365],[134,283],[82,314],[30,453],[137,-118],[195,0],[220,-165],[204,-3],[248,-122],[269,-71],[98,-297],[162,-231],[91,-10],[58,-182],[513,-434],[83,-32],[329,-422],[134,-523],[304,-307],[140,-9],[231,216],[193,392],[184,153],[141,7],[293,379],[154,51],[286,-105],[370,-203],[62,-177],[168,-164],[367,33],[272,-146],[190,-22],[308,74],[221,-103],[77,-307],[185,-139],[133,355],[240,-18],[157,132],[38,236],[195,608],[-176,377],[-5,119],[-154,119],[-35,357],[-140,193],[92,760],[13,595],[403,222],[3,457],[84,162],[-198,364],[-3,185],[147,85],[-26,252],[256,369],[-77,227],[60,238],[-99,258],[-146,217],[0,282],[100,-23],[215,201],[70,-37],[246,247],[245,75],[99,168],[8,182],[127,393],[283,288],[-34,199],[176,176],[150,484],[-3,135],[153,414]]],"transform":{"scale":[0.007086925546398242,-0.004800048000480004],"translate":[125.65726614286109,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/zg.json b/src/onegov/election_day/static/mapdata/2025/zg.json new file mode 100644 index 0000000000..04824503b1 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/zg.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":1701,"properties":{"id":1701,"name":"Baar"},"arcs":[[-1,-2,-3,-4,-5,-6]]},{"type":"Polygon","id":1702,"properties":{"id":1702,"name":"Cham"},"arcs":[[-7,-8,-9,-10,-11]]},{"type":"Polygon","id":1703,"properties":{"id":1703,"name":"Hünenberg"},"arcs":[[-12,-13,6]]},{"type":"Polygon","id":1704,"properties":{"id":1704,"name":"Menzingen"},"arcs":[[-14,1,-15,-16,-17]]},{"type":"Polygon","id":1705,"properties":{"id":1705,"name":"Neuheim"},"arcs":[[-18,14,0]]},{"type":"Polygon","id":1706,"properties":{"id":1706,"name":"Oberägeri"},"arcs":[[16,-19,-20]]},{"type":"Polygon","id":1707,"properties":{"id":1707,"name":"Risch"},"arcs":[[10,-21,-22,11]]},{"type":"Polygon","id":1708,"properties":{"id":1708,"name":"Steinhausen"},"arcs":[[4,-23,8,-24]]},{"type":"Polygon","id":1709,"properties":{"id":1709,"name":"Unterägeri"},"arcs":[[13,19,-25,-26,-27,-28,2]]},{"type":"Polygon","id":1710,"properties":{"id":1710,"name":"Walchwil"},"arcs":[[-29,26,-30,-31]]},{"type":"MultiPolygon","id":1711,"properties":{"id":1711,"name":"Zug"},"arcs":[[[-32,20,9,22,3,27,28]],[[29,25,-33]]]}]}},"arcs":[[[52986,63362],[43,134],[-140,471],[15,269],[272,694],[74,385],[79,1455],[45,223],[132,253],[-15,360],[-89,227],[-177,183],[-189,360],[44,513],[137,386],[-6,307],[-114,191],[524,633],[305,716],[30,364],[133,299],[-47,123],[-1,934],[217,1171],[191,-20],[189,71],[397,-6],[74,224],[227,160],[84,358],[-163,201],[-47,608],[98,316],[97,93],[320,110],[600,523],[320,24],[99,-158],[575,126],[269,656],[230,274],[85,250],[319,235],[359,459],[122,245],[236,250],[65,148],[8,299],[217,423],[27,369],[189,566],[-833,1111],[-310,41],[29,67]],[[55027,43329],[269,332],[40,194],[-69,114],[-205,36],[-816,308],[-56,298],[125,299],[-26,768],[-80,268],[-35,827],[83,343],[251,384],[-44,515],[-165,462],[10,310],[-345,334],[-91,327],[221,954],[-122,385],[-242,297],[40,425],[-24,392],[75,466],[221,373],[79,665],[103,259],[-38,593],[-77,320],[0,250],[-253,495],[111,199],[156,85],[105,193],[-31,243],[-276,750],[0,274],[-89,184],[-228,91],[-124,463],[7,717],[-182,151],[-344,123],[-373,-33],[-119,170],[66,460],[-162,303],[-181,461],[-103,504],[36,151],[153,150],[100,459],[138,158],[71,326],[165,217],[-9,263],[109,313],[16,450],[118,215]],[[53648,42045],[250,148],[355,-131],[263,115],[141,216],[192,165],[17,217],[-174,380],[335,174]],[[34327,65126],[41,77],[49,-1285],[-352,-78],[-322,-332],[63,-107],[-273,-314],[704,-729],[104,-289],[239,-287],[897,462],[-41,145],[-134,-58],[-80,159],[111,832],[397,195],[345,304],[207,-230],[407,808],[131,-113],[-32,-237],[164,-383],[-228,-388],[883,-844],[144,264],[400,-365],[80,-2],[224,-256],[785,-771],[247,-365],[141,-87],[187,-246],[114,72],[99,241],[287,251],[174,26],[625,-154],[167,1170],[308,237],[336,502],[58,324],[205,-29],[408,-310],[685,-1171],[110,-110],[-77,-533],[-122,-380],[-108,-157],[-105,-322],[-171,91],[-42,-163],[-249,87],[-183,-598],[-10,-435],[-171,-12],[-132,-493],[172,-312],[494,-430],[25,50],[517,-392],[224,-19],[534,-439],[-26,-397],[79,-518],[174,-139],[183,-515],[183,224],[118,383],[120,39],[680,2],[530,-25],[131,-246],[14,-276],[166,-302],[185,-159],[112,-358],[248,-315],[163,-74],[132,-235],[17,-338],[-115,-357],[329,-694],[-799,-273],[-312,-357],[-144,-334],[-13,-516],[172,-2],[-105,-1021],[568,-974],[357,-57],[142,79],[341,-748],[-80,-219],[512,-1529],[379,82],[142,-65],[-43,-739],[243,-290],[866,-50],[34,-232],[331,154],[90,-244],[117,-83],[295,62],[504,-90],[262,-189],[169,137],[589,290],[266,275],[2,270],[265,-22],[-15,-268],[683,-2815],[185,-807],[77,-9],[158,-269]],[[33702,78587],[594,-929],[357,-256],[227,-421],[245,-356],[-271,-470],[-351,-477],[-246,-386],[-365,-802],[-157,-432],[-43,-638],[-339,3],[-222,84],[-137,-763],[61,-1357],[325,-35],[425,-182],[138,-126],[225,-61],[366,-593],[120,-253],[351,-59],[54,221],[189,-31],[290,-191],[6,-221],[-97,-194],[33,-385],[-210,-4],[-45,-468],[16,-426],[-174,-167],[-36,-218],[-525,-431],[-48,93],[-256,-456],[116,-510],[73,-514],[-111,-43],[-6,-312],[53,-695]],[[58331,82036],[-44,390],[-459,394],[-514,65],[-427,-82],[-470,76],[-442,-9],[-289,263],[-163,60],[-535,317],[-479,-43],[-745,-22],[-514,459],[-183,567],[-249,257],[-1192,905],[-233,-735],[-43,-224],[-562,16],[-841,172],[-551,-35],[-341,-349],[-239,75],[-17,108],[-221,124],[-390,86],[-861,385],[-263,163],[-183,19],[-16,-126],[-374,-392],[-412,-263],[-15,-379],[-93,-335],[-858,510],[-391,391],[29,-459],[-29,-435],[-197,-338],[-58,-702],[68,-398],[-107,-234],[-190,-195],[-234,85],[-85,257],[-244,105],[-146,146],[-434,11],[-246,62],[-250,-87],[-24,141],[-337,16],[-180,-77],[-186,104],[-387,-52],[-194,110],[-165,282],[72,284],[-141,133],[-182,-517],[-887,134],[-334,13],[-1378,-150],[-61,-447],[124,-946],[-55,-270],[74,-58],[-154,-618],[-235,-8],[-392,105],[-318,-445],[-270,-34],[-377,-321],[-69,-6],[-696,209],[275,-538],[-410,-419],[-245,-363],[-209,-119],[40,-88],[-483,-223],[-491,-20],[-622,113]],[[7155,91233],[-197,-1041],[-217,-720],[-95,-467],[-51,-474],[-97,-2928],[128,-6],[55,-335],[-37,-291],[-12,-865],[294,-755],[103,-732],[13,-305],[-58,-482],[-133,-421],[1,-920],[226,-427],[87,-446],[183,-687],[338,-503],[291,-656],[-99,-145],[-70,-477],[22,-468],[251,-158],[197,-55],[68,-596],[171,-463],[470,-377],[-15,-414],[178,-393],[942,-1946],[-214,-714],[-126,-183],[-202,-599],[-63,-414],[-201,51],[90,-687],[129,-434],[-98,-301],[239,-596],[140,-53],[152,88],[26,-250],[-7,-624],[126,-640],[63,-473],[-29,-381],[74,-989],[697,-139],[220,-228],[-142,-579],[215,-140],[327,-119],[213,-423],[106,-129],[-106,-418],[146,-97],[189,-256],[250,-532],[212,-523],[405,-330],[378,-587],[349,-113],[353,-274],[655,-286],[315,-256],[127,-261],[1316,-104],[259,-36],[660,-206],[-88,-435],[4,-517],[-34,-466],[498,-1153],[227,-85],[233,111],[16,188],[112,-114],[247,-80],[318,-594],[696,-706],[2440,-1384]],[[27718,76407],[-863,444],[-29,-27],[-311,407],[-220,-257],[-118,-408],[-370,-99],[-232,-154],[-225,577],[132,149],[-52,275],[307,267],[-170,201],[-280,437],[-316,180],[-353,-54],[-114,891],[-397,-107],[-178,-173],[-411,744],[-79,44],[-318,-152],[-417,-81],[-505,-27],[-372,-181],[-145,23],[-148,389],[-180,628],[-239,388],[-332,613],[-286,164],[-188,251],[-191,520],[-227,-111],[-112,88],[-386,-276],[-482,-210],[-430,364],[227,39],[226,124],[-310,577],[-599,-89],[11,467],[-93,-106],[-677,13],[-40,-52],[-17,548],[-139,269],[-234,271],[-69,168],[62,760],[-235,-30],[-423,-168],[-259,-264],[-210,264],[-104,305],[-75,-16],[-351,768],[-145,219],[-353,-542],[-310,-261],[-615,-139],[-361,69],[-165,-75],[-1051,245],[-648,439],[-338,-4],[-815,-533],[-363,-159],[-151,-3],[-684,-195],[-444,-85],[-109,806],[-149,592],[-351,89],[-223,288],[-211,-70],[-115,266],[5,349],[-92,730],[-58,138],[-172,105],[38,216],[-74,713],[-65,218],[-50,800],[52,1035]],[[26953,62350],[137,372],[132,680],[113,968],[-49,11],[-30,732],[-609,295],[-270,274],[-86,207],[-136,806],[-151,180],[-307,159],[-5,106],[196,871],[344,640],[-254,266],[-114,466],[-183,244],[-226,-269],[-234,30],[-135,-178],[-344,272],[-192,291],[-314,694],[224,335],[237,247],[-353,633],[795,721],[-65,210],[939,372],[-165,716],[882,860],[-190,209],[-373,220],[-384,637],[582,-311],[490,367],[863,724]],[[26006,51551],[469,8157],[-96,797],[147,151],[16,736],[303,661],[108,297]],[[22004,53810],[4002,-2259]],[[6695,44983],[480,-479],[188,-1244],[175,146],[181,45],[155,-61],[331,73],[300,250],[816,148],[26,465],[555,212],[1092,-280],[798,7],[11,826],[39,526],[1749,-255],[2631,609],[218,293],[166,-163],[290,136],[353,-8],[129,227],[77,359],[-271,889],[830,497],[-96,1060],[191,390],[242,45],[115,-247],[420,137],[85,186],[88,-55],[127,177],[64,-103],[135,362],[1,143],[307,193],[129,426],[264,285],[116,238],[1802,2372]],[[7155,91233],[-132,463],[32,431],[-159,354],[-18,152],[83,527],[-79,227],[-150,182],[-209,472],[-300,294],[-5,268],[132,221],[315,232],[274,584],[-4,141],[-153,242],[-82,346],[-286,143],[-139,144],[-125,437],[-227,501],[-114,527],[-31,502],[-93,302],[-263,504],[-266,317],[-343,253],[127,-274],[126,-449],[44,-602],[-44,-407],[-207,-630],[-881,-1650],[-214,-586],[-66,-494],[5,-995],[-61,-526],[-140,-436],[-381,-586],[-1468,-1751],[-558,-737],[-406,-764],[-206,-543],[-116,-393],[-302,-1233],[-65,-666],[44,-418],[461,-2711],[178,-820],[205,-447],[669,-902],[189,-338],[173,-438],[134,-607],[23,-460],[-161,-2494],[21,-827],[81,-496],[268,-1106],[108,-824],[96,-1439],[148,-729],[757,-2169],[141,-542],[50,-542],[-36,-542],[-79,-375],[-185,-513],[-566,-1116],[-292,-707],[-148,-542],[-100,-543],[-104,-807],[-81,-819],[-10,-542],[24,-563],[60,-522],[281,-1626],[332,-1782],[101,-211],[282,-176],[1427,-362],[292,-114],[454,-331],[235,-277],[295,-542],[135,-447],[513,-2264],[477,-2169],[88,-542],[59,-832],[-17,-2421],[-26,-377],[-91,-421],[-210,-500]],[[55027,43329],[291,-1014],[177,-993],[-41,-681],[126,-192],[152,-56],[78,312],[342,114],[128,126],[72,385],[369,652],[549,268],[527,-195],[135,37],[311,-105],[208,91],[120,138],[486,366],[426,-228],[174,-214],[174,146],[330,-139],[570,58],[189,197],[272,45],[174,155],[49,182],[259,355],[525,190],[409,310],[365,126],[250,-111],[292,-573],[91,-97],[314,-598],[372,-399],[606,-126],[442,181]],[[67776,73754],[194,-255],[310,-29],[81,79],[239,5],[200,-237],[257,-145],[143,-591],[-129,-560],[-4,-245],[195,-591],[80,-120],[221,-1176],[-547,-306],[54,-472],[365,-1144],[-248,-529],[356,-452],[-54,-836],[221,-284],[231,162],[47,-109],[170,44],[195,-483],[131,-146],[-63,-155],[-301,-209],[-255,-558],[-89,55],[-353,5],[-44,296],[-246,358],[-451,509],[-270,-184],[-345,57],[-439,259],[-608,103],[-42,-379],[-324,-75],[5,-413],[-221,-88],[-320,365],[-490,-68],[-173,-437],[-137,-1],[-270,-343],[-358,131],[-155,128],[-91,-628],[-326,521],[-154,150],[-105,-234],[-310,367],[-337,174],[-346,326],[-253,45],[-489,1173],[-457,-60],[-287,-219],[-428,165],[-453,406],[-319,-32],[-405,621],[-267,134],[-116,173],[-380,72],[-99,-314],[-478,171],[-33,-312],[-91,-305],[-136,27],[-748,-1095],[-400,-641],[-162,-207],[-375,-213],[140,-267],[85,-332],[-212,-214],[-281,-197],[-34,198],[-255,50],[-268,333],[-144,-41],[61,-291],[-200,-65],[-182,173],[-203,-179],[-104,-384],[-91,170],[-147,-132],[-270,-99],[-132,45],[-103,-196],[61,-285],[-179,222],[-146,13],[-163,-114],[-280,-548],[-203,155],[-254,392]],[[88433,48007],[-350,155],[-396,360],[-377,-20],[-312,136],[-247,1571],[-87,337],[117,236],[-29,99],[88,555],[-74,719],[10,456],[93,508],[-192,420],[-54,394],[92,456],[-480,141],[-246,18],[-236,-87],[-347,-287],[-214,-77],[-328,67],[-643,533],[-320,61],[-472,-364],[-250,-90],[-500,-71],[-420,-161],[-496,-126],[-352,-196],[-651,-299],[-376,17],[-420,190],[-142,134],[-43,339],[127,515],[-87,270],[-262,121],[-290,47],[-490,17],[-755,-98],[-177,24],[-384,201],[-360,97],[-663,-69],[-314,-6],[-623,128],[-392,170],[-245,238],[-153,369],[-9,241],[62,449],[193,394],[115,585],[114,255],[340,380],[190,297],[292,594],[56,249],[-92,323],[-530,429],[-102,197],[-34,412],[-131,453],[-594,1165],[-585,1250],[-392,723],[-96,408],[19,378],[110,503],[13,309],[-252,310],[-358,240],[-221,307],[-288,247],[-83,233],[37,294],[229,619],[9,251],[-106,349],[-283,432],[-258,649],[-79,271],[-74,602],[-93,388],[-332,568],[-387,416],[-124,403],[-25,377],[-159,223],[-542,258],[-191,182],[-184,271],[-136,419],[-119,174],[-932,467],[-302,-198],[-229,-529],[-392,-618]],[[65340,42042],[153,82],[27,139],[251,232],[93,175],[121,23],[300,246],[369,563],[406,365],[348,-257],[301,295],[180,-22],[188,122],[868,-65],[309,-73],[248,-118],[700,194],[331,336],[342,193],[163,8],[349,-132],[163,-252],[788,-1002],[306,92],[264,-286],[220,242],[247,192],[251,271],[587,320],[295,15],[521,-414],[282,-427],[144,-87],[197,193],[831,171],[164,-233],[202,-84],[32,114],[598,-154],[352,-58],[851,143],[349,-209],[656,192],[405,33],[182,-99],[663,-29],[699,-91],[362,39],[498,104],[279,200],[239,320],[148,31],[830,-223],[573,-336],[404,-44],[378,19],[320,-86],[894,239],[75,528],[-172,442],[18,181],[303,367],[184,288],[124,24],[109,373],[-167,219],[-207,940],[-129,401],[184,165],[336,-18],[196,101],[385,-79],[227,52],[215,138],[152,462],[39,259]],[[67776,73754],[-312,-108],[-333,-347],[-361,-449],[-205,-90],[-263,87],[-125,250],[-93,427],[-163,129],[-210,457],[-101,332],[-62,387],[13,237],[314,267],[-23,242],[-227,384],[13,257],[285,647],[39,417],[-86,206],[-229,210],[-214,285],[-254,640],[-164,285],[-222,226],[-313,3],[-588,-337],[-437,160],[-365,388],[-224,85],[-244,-116],[-324,-620],[-212,-264],[-276,-187],[-561,-128],[-174,75],[-163,361],[-25,572],[-64,397],[-265,644],[-43,485],[162,443],[546,802],[66,239],[-61,280],[-140,155],[-275,24],[-415,-217],[-298,-45],[-392,95],[-302,221],[-175,365],[-167,43],[48,-525],[-66,-206],[-148,-133],[-450,-189],[-117,34]],[[69960,6860],[389,1487],[1000,334],[3647,-87],[965,-488],[537,-31],[777,15],[93,-149],[573,50],[855,-150],[848,7],[1101,753],[225,-90],[270,351],[880,559],[157,2275],[2638,5012],[614,420],[778,1012],[537,452],[247,554],[24,314],[-163,503],[-127,893],[343,223],[457,41],[152,66],[369,-113],[235,56],[246,-56],[278,156],[275,275],[1339,77],[208,-40],[-18,241],[-160,-58],[58,215],[-146,314],[323,-18],[-184,207],[58,44],[-113,443],[69,154],[-201,-98],[-96,176],[188,33],[-147,294],[-1,132],[193,-96],[180,28],[89,132],[-70,257],[167,265],[34,230],[170,25],[141,234],[185,-120],[75,254],[130,-8],[-7,191],[240,-130],[160,175],[-87,113],[70,253],[144,81],[32,167],[152,-130],[237,106],[-303,393],[257,11],[-99,429],[76,162],[322,324],[298,-231],[143,297],[213,92],[169,-33],[240,167],[-106,295],[232,119],[56,134],[-47,197],[97,150],[-100,109],[111,355],[-85,132],[126,275],[90,34],[11,217],[149,96],[-88,241],[250,397],[220,166],[-99,107],[30,337],[-141,136],[171,37],[292,-79],[158,311],[-37,95],[-163,-57],[-99,208],[-244,88],[160,103],[50,144],[-156,147],[-59,379],[123,123],[80,-99],[93,102],[-67,312],[84,290],[134,87],[3,144],[163,72],[47,-109],[327,-97],[-79,203],[-7,290],[-196,180],[-93,176],[21,146],[214,117],[56,236],[110,144],[-111,156],[-274,-55],[-389,252],[-69,505],[-154,223],[-136,890],[15,329],[159,692],[254,176],[117,380],[282,758],[339,595],[90,390],[98,230],[251,226],[283,417],[65,292],[113,158],[504,62],[175,204],[104,297],[440,360],[234,81],[194,358],[586,150],[104,-119],[89,-277],[108,-66],[77,131],[73,467],[466,272],[212,1],[-101,269],[-197,170],[-434,473],[-134,750],[106,287],[92,488],[-174,751],[-198,299],[-13,649],[61,387],[-55,197],[-338,197],[-82,99],[-70,315],[50,191],[-339,1671],[-210,127],[-525,141],[-273,38],[-362,-123],[-364,-205],[-549,-158],[-567,-99],[-579,48],[-377,-94],[-541,-244],[-379,-86],[-302,-22],[-337,-276],[-584,-384],[-360,-136],[-93,-390],[-345,-380],[-775,31],[-214,104],[-545,-6],[-676,-164],[-278,10],[-505,99]],[[65340,42042],[581,-1454],[-112,-8],[-92,-180],[216,-283],[313,-623],[172,-104],[193,-490],[-87,-608],[-76,-100],[-61,-657],[141,-584],[-26,-447],[138,-116],[171,-874],[-33,-175],[-235,-386],[-94,-441],[-73,-119],[278,-757],[2045,-5228],[-902,-3926],[-63,-712],[-208,-668],[21,-281],[-213,-722],[-105,-175],[67,-545],[-183,-525],[10,-130],[404,22],[118,-99],[121,144],[455,147],[403,-115],[388,-13],[119,88],[410,-34],[250,-72],[530,-64],[38,1015],[170,519],[394,468],[220,-205],[233,-77],[468,-417],[211,-105],[573,-504],[140,-184],[356,-239],[341,-51],[377,-222],[399,-287],[150,-53],[-68,-209],[-220,-169],[-312,-94],[-834,78],[-276,-12],[-237,94],[-412,5],[-319,307],[-332,-91],[-280,33],[-267,-333],[-129,-520],[52,-283],[-151,-236],[437,-621],[-109,-206],[69,-349],[-101,-203],[-85,-434],[33,-121],[188,178],[582,241],[315,39],[41,90],[225,-97],[187,141],[162,-342],[44,-379],[-243,-289],[125,-153],[-20,-340],[214,-169],[128,-7],[411,-304],[157,-217],[-370,-287],[-196,54],[-103,-363],[-305,148],[-201,-238],[-377,-109],[-904,-398],[-477,75],[-289,-109],[-237,62],[-226,188],[-381,443],[660,-8020]],[[28392,26813],[2820,10882],[-5206,13856]],[[6695,44983],[-578,-1202],[-108,-424],[-27,-465],[51,-523],[79,-346],[600,-1902],[183,-746],[74,-547],[23,-543],[-22,-543],[-67,-543],[-113,-542],[-162,-543],[-213,-543],[-273,-536],[301,-956],[123,-464],[588,-1568],[214,-1170],[98,-318],[-42,-331],[-132,-215],[-133,-428],[113,-465],[409,-95],[-336,-1470],[-303,-366],[-128,-585],[8,-224],[352,-1063],[298,-349],[207,-418],[302,-442],[55,246],[-106,219],[200,313],[117,-168],[100,35],[438,-488],[473,372],[95,136],[241,-132],[193,174],[119,-570],[309,214],[-26,310],[54,136],[609,-20],[108,-203],[559,569],[85,-162],[142,-32],[313,-323],[443,322],[-222,250],[270,292],[63,-80],[746,243],[1361,1244],[476,594],[390,355],[-65,423],[147,124],[605,-41],[549,-172],[90,-145],[566,431],[102,-144],[522,973],[104,36],[143,-840],[326,-2626],[87,-1026],[39,5],[283,-2115],[92,-185],[147,-795],[236,-915],[78,-532],[-43,-55],[142,-610],[93,-686],[254,-141],[234,-1],[1384,1420],[300,217],[469,197],[306,87],[420,197],[119,99],[329,43],[117,232],[-68,330],[197,-11],[48,225],[227,158],[-141,109],[4268,4593]],[[26953,62350],[471,-81],[603,-148],[-12,79],[519,296],[490,172],[219,173],[175,448],[572,-109],[310,-11],[147,-959],[266,90],[772,504],[-50,256],[721,481],[-275,481],[910,374],[392,242],[126,-1],[1018,489]],[[33702,78587],[-94,166],[-1123,-292],[-484,16],[-129,-58],[-323,-288],[-370,-188],[-423,-123],[-347,-291],[-888,-838],[-527,-367],[-138,199],[-665,-94],[-221,43],[-252,-65]],[[60296,2152],[343,-233],[390,-74],[409,34],[204,80],[584,332],[527,501],[178,3],[526,136],[896,453],[250,1497],[127,164],[349,276],[267,454],[175,173],[359,177],[192,236],[214,115],[462,-327],[207,-198],[570,-15],[2435,924]],[[56555,8945],[125,-60],[-27,-125],[244,-884],[23,-225],[506,-272],[293,-389],[217,-358],[47,-191],[184,-382],[341,-597],[36,-258],[196,-407],[199,-277],[77,-312],[229,-375],[161,-142],[117,-226],[154,-483],[275,-623],[344,-207]],[[49463,25151],[76,-471],[380,-614],[65,-170],[33,-715],[175,-323],[176,-484],[463,-647],[293,89],[439,-47],[369,43],[214,-59],[290,-187],[671,-53],[299,-195],[394,-398],[148,-373],[387,-433],[59,-223],[14,-629],[-133,-410],[-18,-240],[71,-415],[334,-300],[121,-641],[146,-439],[-189,-287],[-258,-157],[-345,-603],[-35,-410],[177,-228],[96,-423],[192,-234],[25,-540],[200,-872],[16,-265],[113,-181],[-199,-272],[397,-267],[250,-46],[242,-362],[8,-124],[295,-301],[189,-404],[-30,-265],[-146,-308],[445,-503],[183,-820]],[[53648,42045],[-84,-125],[7,-266],[-307,-389],[-351,-277],[-163,-201],[-294,-42],[-100,-225],[-351,-542],[-605,-673],[-755,-745],[-60,-316],[-415,-109],[-197,-211],[-283,-67],[-315,-309],[-133,-200],[-5,-287],[-239,-594],[-187,-319],[5,-196],[-76,-612],[16,-533],[-325,-1445],[-69,-900],[-89,-491],[1,-287],[86,-125],[129,-445],[28,-248],[138,-480],[-38,-283],[71,-161],[236,-290],[28,-249],[-54,-296],[4,-587],[134,-363],[391,-491],[169,-115],[-158,-447],[-136,-541],[161,-1412]],[[49463,25151],[-224,-88],[-144,82],[-336,-45],[-154,95],[-108,-131],[-212,-77],[-424,44],[-435,-345],[-157,-6],[-150,-151],[-137,107],[-412,-280],[-28,-196],[-374,-305],[-18,-127],[-197,-167],[-340,914],[-239,1447],[-590,1798],[-1605,-56],[-168,113],[-373,-281],[-177,-87],[-43,-128],[-217,-112],[-116,-150],[-360,486],[-398,272],[-207,26],[-565,-147],[-584,-1191],[-779,-330],[-924,382],[-522,-385],[30,-1124],[-51,-220],[-284,-147],[-231,-256],[-117,-261],[-111,-440],[-178,-248],[171,-245],[48,-182],[-370,-665],[-105,-113],[-72,-303],[-136,-261],[-521,-583],[-116,-230],[-36,-323],[-269,-311],[-157,-48],[-340,-393],[-2083,-483]],[[55584,6964],[206,238],[84,927],[-5,221],[75,135],[332,357],[279,103]],[[32818,19296],[-137,-8171],[9418,-5992],[49,-66],[418,403],[250,-118],[126,73],[229,556],[191,189],[731,-18],[248,45],[221,-54],[223,54],[271,-107],[208,144],[106,-29],[518,110],[90,120],[605,60],[238,-174],[314,13],[644,165],[190,-40],[294,171],[49,231],[175,151],[358,423],[186,100],[92,199],[239,231],[417,-78],[136,60],[379,-336],[34,-80],[338,52],[150,-74],[412,33],[225,99],[252,-12],[413,131],[1089,-342],[767,328],[372,-32],[662,-127],[300,60],[276,-683]],[[28392,26813],[4426,-7517]],[[55584,6964],[106,-395],[48,-698],[-12,-368],[68,-444],[12,-528],[153,-566],[179,-214],[-15,-318],[-289,-581],[-140,-432],[-98,-705],[-96,-57],[-39,-405],[-67,-144],[176,-598],[224,-235],[201,-18],[193,-168],[250,-90],[958,49],[303,85],[241,309],[436,151],[601,53],[254,141],[1065,1364]]],"transform":{"scale":[0.0060715681600489475,-0.004800048000480005],"translate":[176.42462778163264,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/mapdata/2025/zh.json b/src/onegov/election_day/static/mapdata/2025/zh.json new file mode 100644 index 0000000000..a9ab415fb9 --- /dev/null +++ b/src/onegov/election_day/static/mapdata/2025/zh.json @@ -0,0 +1 @@ +{"type":"Topology","objects":{"municipalities":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":1,"properties":{"id":1,"name":"Aeugst am Albis"},"arcs":[[-1,-2,-3,-4,-5,-6]]},{"type":"Polygon","id":2,"properties":{"id":2,"name":"Affoltern am Albis"},"arcs":[[-7,-8,-9,3,-10,-11,-12]]},{"type":"Polygon","id":3,"properties":{"id":3,"name":"Bonstetten"},"arcs":[[-13,-14,-15,-16,-17]]},{"type":"Polygon","id":4,"properties":{"id":4,"name":"Hausen am Albis"},"arcs":[[-18,-19,0,-20,-21,-22]]},{"type":"Polygon","id":5,"properties":{"id":5,"name":"Hedingen"},"arcs":[[16,-23,7,-24]]},{"type":"Polygon","id":6,"properties":{"id":6,"name":"Kappel am Albis"},"arcs":[[-25,-26,-27,17,-28]]},{"type":"Polygon","id":7,"properties":{"id":7,"name":"Knonau"},"arcs":[[24,-29,-30,-31]]},{"type":"Polygon","id":8,"properties":{"id":8,"name":"Maschwanden"},"arcs":[[-32,29,-33,-34]]},{"type":"Polygon","id":9,"properties":{"id":9,"name":"Mettmenstetten"},"arcs":[[-35,9,2,-36,25,30,31]]},{"type":"Polygon","id":10,"properties":{"id":10,"name":"Obfelden"},"arcs":[[-37,10,34,33,-38]]},{"type":"Polygon","id":11,"properties":{"id":11,"name":"Ottenbach"},"arcs":[[11,36,-39]]},{"type":"Polygon","id":12,"properties":{"id":12,"name":"Rifferswil"},"arcs":[[35,1,18,26]]},{"type":"Polygon","id":13,"properties":{"id":13,"name":"Stallikon"},"arcs":[[-40,-41,4,8,22,15,-42,-43,-44,-45]]},{"type":"Polygon","id":14,"properties":{"id":14,"name":"Wettswil am Albis"},"arcs":[[14,-46,41]]},{"type":"Polygon","id":22,"properties":{"id":22,"name":"Benken (ZH)"},"arcs":[[-47,-48,-49,-50,-51]]},{"type":"Polygon","id":23,"properties":{"id":23,"name":"Berg am Irchel"},"arcs":[[-52,-53,-54,-55,-56]]},{"type":"Polygon","id":24,"properties":{"id":24,"name":"Buch am Irchel"},"arcs":[[-57,-58,53,-59,-60,-61]]},{"type":"Polygon","id":25,"properties":{"id":25,"name":"Dachsen"},"arcs":[[-62,-63,48,-64]]},{"type":"Polygon","id":26,"properties":{"id":26,"name":"Dorf"},"arcs":[[59,-65,-66,-67,-68]]},{"type":"Polygon","id":27,"properties":{"id":27,"name":"Feuerthalen"},"arcs":[[-69,-70,-71]]},{"type":"Polygon","id":28,"properties":{"id":28,"name":"Flaach"},"arcs":[[-72,-73,-74,-75,51,-76]]},{"type":"Polygon","id":29,"properties":{"id":29,"name":"Flurlingen"},"arcs":[[69,-77,-78]]},{"type":"Polygon","id":31,"properties":{"id":31,"name":"Henggart"},"arcs":[[-79,-80,-81,-82,66]]},{"type":"Polygon","id":33,"properties":{"id":33,"name":"Kleinandelfingen"},"arcs":[[72,-83,-84,-85,-86]]},{"type":"Polygon","id":34,"properties":{"id":34,"name":"Laufen-Uhwiesen"},"arcs":[[76,68,-87,-88,49,62,-89]]},{"type":"Polygon","id":35,"properties":{"id":35,"name":"Marthalen"},"arcs":[[-90,46,-91,82,71,-92]]},{"type":"Polygon","id":37,"properties":{"id":37,"name":"Ossingen"},"arcs":[[-93,-94,84,-95,-96,-97,-98]]},{"type":"Polygon","id":38,"properties":{"id":38,"name":"Rheinau"},"arcs":[[63,47,89,-99]]},{"type":"Polygon","id":39,"properties":{"id":39,"name":"Thalheim an der Thur"},"arcs":[[92,-100,-101,-102,-103,-104]]},{"type":"Polygon","id":40,"properties":{"id":40,"name":"Trüllikon"},"arcs":[[83,90,50,87,-105,-106,94]]},{"type":"Polygon","id":41,"properties":{"id":41,"name":"Truttikon"},"arcs":[[-107,95,105,-108]]},{"type":"Polygon","id":43,"properties":{"id":43,"name":"Volken"},"arcs":[[52,74,-109,64,58]]},{"type":"Polygon","id":51,"properties":{"id":51,"name":"Bachenbülach"},"arcs":[[-110,-111,-112,-113]]},{"type":"Polygon","id":52,"properties":{"id":52,"name":"Bassersdorf"},"arcs":[[-114,-115,-116,-117,-118]]},{"type":"Polygon","id":53,"properties":{"id":53,"name":"Bülach"},"arcs":[[-119,-120,-121,-122,111,-123,-124,-125]]},{"type":"Polygon","id":54,"properties":{"id":54,"name":"Dietlikon"},"arcs":[[117,-126,-127,-128,-129]]},{"type":"Polygon","id":55,"properties":{"id":55,"name":"Eglisau"},"arcs":[[118,-130,-131,-132,-133,-134,-135,-136,-137,-138]]},{"type":"Polygon","id":56,"properties":{"id":56,"name":"Embrach"},"arcs":[[-139,-140,-141,120,-142,-143,-144,-145]]},{"type":"Polygon","id":57,"properties":{"id":57,"name":"Freienstein-Teufen"},"arcs":[[-146,54,57,-147,142,-148,136]]},{"type":"MultiPolygon","id":58,"properties":{"id":58,"name":"Glattfelden"},"arcs":[[[129,124,-149,-150,-151,-152]],[[-153,131,-154]]]},{"type":"Polygon","id":59,"properties":{"id":59,"name":"Hochfelden"},"arcs":[[123,-155,-156,-157,148]]},{"type":"Polygon","id":60,"properties":{"id":60,"name":"Höri"},"arcs":[[-158,-159,-160,154,122,110]]},{"type":"Polygon","id":61,"properties":{"id":61,"name":"Hüntwangen"},"arcs":[[132,152,-161,-162,-163]]},{"type":"Polygon","id":62,"properties":{"id":62,"name":"Kloten"},"arcs":[[-164,-165,-166,-167,-168,-169,113,128,-170]]},{"type":"Polygon","id":63,"properties":{"id":63,"name":"Lufingen"},"arcs":[[166,-171,139,-172]]},{"type":"Polygon","id":64,"properties":{"id":64,"name":"Nürensdorf"},"arcs":[[168,-173,-174,-175,114]]},{"type":"Polygon","id":65,"properties":{"id":65,"name":"Oberembrach"},"arcs":[[138,-176,-177,-178,172,167,171]]},{"type":"Polygon","id":66,"properties":{"id":66,"name":"Opfikon"},"arcs":[[-179,-180,-181,163]]},{"type":"Polygon","id":67,"properties":{"id":67,"name":"Rafz"},"arcs":[[134,-182,-183]]},{"type":"Polygon","id":68,"properties":{"id":68,"name":"Rorbas"},"arcs":[[141,119,137,147]]},{"type":"Polygon","id":69,"properties":{"id":69,"name":"Wallisellen"},"arcs":[[169,127,-184,-185,178]]},{"type":"Polygon","id":70,"properties":{"id":70,"name":"Wasterkingen"},"arcs":[[-186,161,-187]]},{"type":"Polygon","id":71,"properties":{"id":71,"name":"Wil (ZH)"},"arcs":[[162,185,-188,181,133]]},{"type":"Polygon","id":72,"properties":{"id":72,"name":"Winkel"},"arcs":[[112,121,140,170,165,-189,-190]]},{"type":"Polygon","id":81,"properties":{"id":81,"name":"Bachs"},"arcs":[[-191,-192,-193,-194,-195,-196,-197]]},{"type":"Polygon","id":82,"properties":{"id":82,"name":"Boppelsen"},"arcs":[[-198,-199,-200,-201]]},{"type":"Polygon","id":83,"properties":{"id":83,"name":"Buchs (ZH)"},"arcs":[[-202,-203,-204,-205,-206,-207,199,-208]]},{"type":"Polygon","id":84,"properties":{"id":84,"name":"Dällikon"},"arcs":[[-209,204,-210,-211,-212]]},{"type":"Polygon","id":85,"properties":{"id":85,"name":"Dänikon"},"arcs":[[-213,205,208,-214,-215]]},{"type":"Polygon","id":86,"properties":{"id":86,"name":"Dielsdorf"},"arcs":[[-216,-217,-218,201]]},{"type":"Polygon","id":87,"properties":{"id":87,"name":"Hüttikon"},"arcs":[[-219,214,-220,-221]]},{"type":"Polygon","id":88,"properties":{"id":88,"name":"Neerach"},"arcs":[[193,-222,155,159,-223,-224]]},{"type":"Polygon","id":89,"properties":{"id":89,"name":"Niederglatt"},"arcs":[[-225,222,158,-226,-227]]},{"type":"Polygon","id":90,"properties":{"id":90,"name":"Niederhasli"},"arcs":[[202,217,-228,226,-229,-230,-231]]},{"type":"Polygon","id":91,"properties":{"id":91,"name":"Niederweningen"},"arcs":[[-232,-233,-234]]},{"type":"Polygon","id":92,"properties":{"id":92,"name":"Oberglatt"},"arcs":[[189,-235,228,225,157,109]]},{"type":"Polygon","id":93,"properties":{"id":93,"name":"Oberweningen"},"arcs":[[196,-236,-237,-238,-239,-240]]},{"type":"Polygon","id":94,"properties":{"id":94,"name":"Otelfingen"},"arcs":[[-241,232,-242,200,206,212,218]]},{"type":"Polygon","id":95,"properties":{"id":95,"name":"Regensberg"},"arcs":[[207,198,-243,237,-244,215]]},{"type":"Polygon","id":96,"properties":{"id":96,"name":"Regensdorf"},"arcs":[[230,-245,-246,-247,-248,-249,209,203]]},{"type":"Polygon","id":97,"properties":{"id":97,"name":"Rümlang"},"arcs":[[-250,244,229,234,188,164,180]]},{"type":"Polygon","id":98,"properties":{"id":98,"name":"Schleinikon"},"arcs":[[241,231,-251,238,242,197]]},{"type":"Polygon","id":99,"properties":{"id":99,"name":"Schöfflisdorf"},"arcs":[[235,195,-252]]},{"type":"Polygon","id":100,"properties":{"id":100,"name":"Stadel"},"arcs":[[156,221,192,-253,149]]},{"type":"Polygon","id":101,"properties":{"id":101,"name":"Steinmaur"},"arcs":[[223,224,227,216,243,236,251,194]]},{"type":"Polygon","id":102,"properties":{"id":102,"name":"Weiach"},"arcs":[[-254,150,252,191]]},{"type":"Polygon","id":111,"properties":{"id":111,"name":"Bäretswil"},"arcs":[[-255,-256,-257,-258,-259,-260]]},{"type":"Polygon","id":112,"properties":{"id":112,"name":"Bubikon"},"arcs":[[-261,-262,-263,-264,-265,-266,-267]]},{"type":"Polygon","id":113,"properties":{"id":113,"name":"Dürnten"},"arcs":[[-268,263,-269,-270]]},{"type":"Polygon","id":114,"properties":{"id":114,"name":"Fischenthal"},"arcs":[[-271,-272,-273,-274,254]]},{"type":"Polygon","id":115,"properties":{"id":115,"name":"Gossau (ZH)"},"arcs":[[-275,-276,-277,261,-278,-279,-280,-281]]},{"type":"Polygon","id":116,"properties":{"id":116,"name":"Grüningen"},"arcs":[[-282,-283,-284,277,260]]},{"type":"Polygon","id":117,"properties":{"id":117,"name":"Hinwil"},"arcs":[[276,-285,255,273,-286,268,262]]},{"type":"Polygon","id":118,"properties":{"id":118,"name":"Rüti (ZH)"},"arcs":[[-287,-288,264,267]]},{"type":"Polygon","id":119,"properties":{"id":119,"name":"Seegräben"},"arcs":[[-289,-290,-291,-292]]},{"type":"Polygon","id":120,"properties":{"id":120,"name":"Wald (ZH)"},"arcs":[[269,285,272,-293,286]]},{"type":"Polygon","id":121,"properties":{"id":121,"name":"Wetzikon (ZH)"},"arcs":[[256,284,275,-294,289,-295]]},{"type":"Polygon","id":131,"properties":{"id":131,"name":"Adliswil"},"arcs":[[-296,39,-297,-298,-299]]},{"type":"Polygon","id":135,"properties":{"id":135,"name":"Kilchberg (ZH)"},"arcs":[[-300,297,-301,-302]]},{"type":"Polygon","id":136,"properties":{"id":136,"name":"Langnau am Albis"},"arcs":[[-303,-304,-305,19,5,40,295]]},{"type":"Polygon","id":137,"properties":{"id":137,"name":"Oberrieden"},"arcs":[[-306,-307,-308]]},{"type":"MultiPolygon","id":138,"properties":{"id":138,"name":"Richterswil"},"arcs":[[[-309,-310]]]},{"type":"Polygon","id":139,"properties":{"id":139,"name":"Rüschlikon"},"arcs":[[298,299,-311,-312,302]]},{"type":"Polygon","id":141,"properties":{"id":141,"name":"Thalwil"},"arcs":[[306,-313,303,311,-314]]},{"type":"Polygon","id":151,"properties":{"id":151,"name":"Erlenbach (ZH)"},"arcs":[[-315,-316,-317]]},{"type":"Polygon","id":152,"properties":{"id":152,"name":"Herrliberg"},"arcs":[[-318,316,-319,-320,-321,-322]]},{"type":"Polygon","id":153,"properties":{"id":153,"name":"Hombrechtikon"},"arcs":[[266,-323,-324,-325,281]]},{"type":"Polygon","id":154,"properties":{"id":154,"name":"Küsnacht (ZH)"},"arcs":[[-326,-327,318,315,-328,-329]]},{"type":"Polygon","id":155,"properties":{"id":155,"name":"Männedorf"},"arcs":[[-330,-331,-332,-333]]},{"type":"Polygon","id":156,"properties":{"id":156,"name":"Meilen"},"arcs":[[-334,321,-335,-336]]},{"type":"Polygon","id":157,"properties":{"id":157,"name":"Oetwil am See"},"arcs":[[-337,330,-338,-339,282,324]]},{"type":"Polygon","id":158,"properties":{"id":158,"name":"Stäfa"},"arcs":[[323,-340,331,336]]},{"type":"Polygon","id":159,"properties":{"id":159,"name":"Uetikon am See"},"arcs":[[335,-341,337,329,-342]]},{"type":"Polygon","id":160,"properties":{"id":160,"name":"Zumikon"},"arcs":[[-343,-344,325]]},{"type":"Polygon","id":161,"properties":{"id":161,"name":"Zollikon"},"arcs":[[-345,-346,342,328,-347]]},{"type":"Polygon","id":172,"properties":{"id":172,"name":"Fehraltorf"},"arcs":[[-348,-349,-350,-351,-352]]},{"type":"Polygon","id":173,"properties":{"id":173,"name":"Hittnau"},"arcs":[[258,-353,-354]]},{"type":"Polygon","id":176,"properties":{"id":176,"name":"Lindau"},"arcs":[[-355,-356,115,174,-357,-358,-359]]},{"type":"Polygon","id":177,"properties":{"id":177,"name":"Pfäffikon"},"arcs":[[294,288,-360,348,-361,-362,-363,352,257]]},{"type":"Polygon","id":178,"properties":{"id":178,"name":"Russikon"},"arcs":[[-364,-365,-366,360,347]]},{"type":"Polygon","id":180,"properties":{"id":180,"name":"Weisslingen"},"arcs":[[-367,-368,364,-369]]},{"type":"Polygon","id":181,"properties":{"id":181,"name":"Wila"},"arcs":[[-370,-371,-372,-373]]},{"type":"Polygon","id":182,"properties":{"id":182,"name":"Wildberg"},"arcs":[[361,365,367,-374,-375,369,-376]]},{"type":"Polygon","id":191,"properties":{"id":191,"name":"Dübendorf"},"arcs":[[-377,-378,183,126,-379,-380,-381]]},{"type":"Polygon","id":192,"properties":{"id":192,"name":"Egg"},"arcs":[[-382,-383,278,283,338,340,334,320]]},{"type":"Polygon","id":193,"properties":{"id":193,"name":"Fällanden"},"arcs":[[-384,-385,-386,-387,376]]},{"type":"Polygon","id":194,"properties":{"id":194,"name":"Greifensee"},"arcs":[[-388,-389,-390,-391]]},{"type":"Polygon","id":195,"properties":{"id":195,"name":"Maur"},"arcs":[[319,326,343,345,-392,385,-393,-394,381]]},{"type":"MultiPolygon","id":196,"properties":{"id":196,"name":"Mönchaltorf"},"arcs":[[[-395,-396,279,382,393]],[[-397,290,293,274]]]},{"type":"Polygon","id":197,"properties":{"id":197,"name":"Schwerzenbach"},"arcs":[[380,-398,388,-399,383]]},{"type":"Polygon","id":198,"properties":{"id":198,"name":"Uster"},"arcs":[[280,395,-400,390,-401,349,359,291,396]]},{"type":"Polygon","id":199,"properties":{"id":199,"name":"Volketswil"},"arcs":[[379,-402,354,-403,350,400,389,397]]},{"type":"Polygon","id":200,"properties":{"id":200,"name":"Wangen-Brüttisellen"},"arcs":[[116,355,401,378,125]]},{"type":"Polygon","id":211,"properties":{"id":211,"name":"Altikon"},"arcs":[[-404,-405,-406,-407,100]]},{"type":"Polygon","id":213,"properties":{"id":213,"name":"Brütten"},"arcs":[[-408,356,173,177]]},{"type":"Polygon","id":214,"properties":{"id":214,"name":"Dägerlen"},"arcs":[[102,-409,-410,-411,79,-412]]},{"type":"Polygon","id":215,"properties":{"id":215,"name":"Dättlikon"},"arcs":[[-413,-414,143,146,56]]},{"type":"Polygon","id":216,"properties":{"id":216,"name":"Dinhard"},"arcs":[[406,-415,-416,-417,408,101]]},{"type":"Polygon","id":218,"properties":{"id":218,"name":"Ellikon an der Thur"},"arcs":[[404,-418,-419,-420]]},{"type":"Polygon","id":219,"properties":{"id":219,"name":"Elsau"},"arcs":[[-421,-422,-423,-424]]},{"type":"Polygon","id":220,"properties":{"id":220,"name":"Hagenbuch"},"arcs":[[-425,-426,-427]]},{"type":"Polygon","id":221,"properties":{"id":221,"name":"Hettlingen"},"arcs":[[-428,-429,80,410,-430]]},{"type":"Polygon","id":223,"properties":{"id":223,"name":"Neftenbach"},"arcs":[[60,67,81,428,-431,-432,412]]},{"type":"Polygon","id":224,"properties":{"id":224,"name":"Pfungen"},"arcs":[[144,413,431,-433,175]]},{"type":"Polygon","id":225,"properties":{"id":225,"name":"Rickenbach (ZH)"},"arcs":[[419,-434,-435,414,405]]},{"type":"Polygon","id":226,"properties":{"id":226,"name":"Schlatt (ZH)"},"arcs":[[-436,-437,-438,-439,422]]},{"type":"Polygon","id":227,"properties":{"id":227,"name":"Seuzach"},"arcs":[[429,409,416,-440]]},{"type":"Polygon","id":228,"properties":{"id":228,"name":"Turbenthal"},"arcs":[[370,374,-441,436,-442,-443]]},{"type":"Polygon","id":230,"properties":{"id":230,"name":"Winterthur"},"arcs":[[434,-444,423,438,-445,-446,357,407,176,432,430,427,439,415]]},{"type":"Polygon","id":231,"properties":{"id":231,"name":"Zell (ZH)"},"arcs":[[-447,444,437,440,373,366]]},{"type":"Polygon","id":241,"properties":{"id":241,"name":"Aesch (ZH)"},"arcs":[[-448,13,-449]]},{"type":"Polygon","id":242,"properties":{"id":242,"name":"Birmensdorf (ZH)"},"arcs":[[42,45,447,-450,-451,-452]]},{"type":"Polygon","id":243,"properties":{"id":243,"name":"Dietikon"},"arcs":[[-453,-454,-455,-456,-457,-458,-459]]},{"type":"Polygon","id":244,"properties":{"id":244,"name":"Geroldswil"},"arcs":[[455,-460,-461]]},{"type":"Polygon","id":245,"properties":{"id":245,"name":"Oberengstringen"},"arcs":[[-462,-463,246,-464]]},{"type":"Polygon","id":246,"properties":{"id":246,"name":"Oetwil an der Limmat"},"arcs":[[211,-465,459,454,-466,219,213]]},{"type":"Polygon","id":247,"properties":{"id":247,"name":"Schlieren"},"arcs":[[458,-467,461,-468,-469]]},{"type":"Polygon","id":248,"properties":{"id":248,"name":"Uitikon"},"arcs":[[43,451,-470,-471]]},{"type":"Polygon","id":249,"properties":{"id":249,"name":"Unterengstringen"},"arcs":[[-472,247,462,466,457],[-473]]},{"type":"Polygon","id":250,"properties":{"id":250,"name":"Urdorf"},"arcs":[[468,469,450,-474,452]]},{"type":"Polygon","id":251,"properties":{"id":251,"name":"Weiningen (ZH)"},"arcs":[[460,464,210,248,471,456]]},{"type":"Polygon","id":261,"properties":{"id":261,"name":"Zürich"},"arcs":[[-475,300,296,44,470,467,463,245,249,179,184,377,386,391,344]]},{"type":"Polygon","id":291,"properties":{"id":291,"name":"Andelfingen"},"arcs":[[103,411,78,65,108,73,85,93]]},{"type":"Polygon","id":292,"properties":{"id":292,"name":"Stammheim"},"arcs":[[96,106,-476]]},{"type":"Polygon","id":293,"properties":{"id":293,"name":"Wädenswil"},"arcs":[[308,-477,-478,-479]]},{"type":"Polygon","id":294,"properties":{"id":294,"name":"Elgg"},"arcs":[[421,-480,424,-481,441,435]]},{"type":"Polygon","id":295,"properties":{"id":295,"name":"Horgen"},"arcs":[[-482,477,-483,20,304,312,305]]},{"type":"Polygon","id":296,"properties":{"id":296,"name":"Illnau-Effretikon"},"arcs":[[351,402,358,445,446,368,363]]},{"type":"Polygon","id":297,"properties":{"id":297,"name":"Bauma"},"arcs":[[259,353,362,375,372,-484,270]]},{"type":"Polygon","id":298,"properties":{"id":298,"name":"Wiesendangen"},"arcs":[[443,433,418,-485,425,479,420]]}]}},"arcs":[[[23601,18738],[23,355],[170,325],[-384,1462],[265,112],[163,-52]],[[23366,18728],[235,10]],[[18871,19074],[172,-414],[376,-185],[362,-14],[399,-264],[172,-25],[365,-229],[264,113],[-127,119],[150,305],[667,63],[280,-136],[657,68],[332,186],[426,67]],[[19569,23854],[28,-75],[-332,-201],[-373,-36],[-128,-409],[-134,-143],[266,-120],[455,-18],[85,-313],[105,-51],[-605,6],[65,-283],[-209,-145],[68,-194],[-1,-517],[-53,-289],[246,6],[314,-764],[182,-189],[-306,-261],[131,-274],[-161,-155],[84,-147],[-425,-208]],[[24260,23328],[-127,58],[-431,-104],[-352,282],[-591,290],[-193,166],[-127,266],[-237,76],[-142,182],[16,-215],[-419,59],[-335,199],[-476,53],[-220,-732],[-299,-143],[-597,125],[-161,-36]],[[23838,20940],[553,166],[350,345],[31,204],[-258,166],[340,152],[97,160],[-145,199],[139,55],[47,402],[-136,-14],[-596,553]],[[11889,25977],[-1191,-554],[-262,-240],[55,-151],[-194,-58],[-41,-162],[-262,-139],[-382,-42]],[[19468,24633],[-393,60],[-684,-120],[-116,164],[-235,-49],[-196,-180],[-250,312],[-163,-248],[-546,237],[-117,-123],[173,-82],[-166,-500],[-323,214],[-410,-109],[-137,-122],[-548,-273],[-227,277],[-135,-101],[-252,14],[-86,144],[-388,-55],[-260,274],[-141,352],[-331,-91],[-84,410],[-565,-6],[-181,378],[-339,-35],[-403,216],[126,76],[-202,310]],[[19569,23854],[-101,779]],[[14425,19558],[282,-33],[59,-174],[-134,-206],[59,-116],[338,80],[-56,484],[-94,173],[245,128],[31,-137],[254,183],[465,23],[437,-195],[261,-259],[449,-162],[113,-214],[70,146],[210,-3],[172,-221],[416,53],[155,-57],[79,252],[635,-229]],[[11476,21945],[182,-57],[350,274],[301,-282],[206,106],[-24,210],[489,-71],[172,-339],[314,-228],[-410,-436],[532,-641],[600,-448],[99,-178],[-131,-57],[269,-240]],[[9612,24631],[302,-360],[469,242],[-9,-499],[215,-432],[165,54],[462,-886],[-100,-147],[307,-457],[53,-201]],[[15751,32390],[159,-124],[-211,-456],[-339,-474],[138,-80],[-610,-517],[231,-84],[-210,-234],[91,-171],[-235,-269],[-157,-61],[-134,-304],[-535,-309],[-294,-101],[132,-376]],[[15927,32404],[-176,-14]],[[20486,30387],[-246,-61],[-34,284],[-313,24],[-306,-112],[-169,157],[12,387],[-479,-33],[-127,82],[-456,38],[-785,-15],[34,242],[-37,590],[-353,-276],[-482,-69],[-60,199],[-293,-44],[-247,520],[-218,104]],[[20410,25404],[167,188],[-566,587],[-2,404],[219,628],[-82,197],[95,303],[241,349],[304,-140],[364,161],[551,35],[117,133],[-477,52],[-432,164],[-279,254],[-234,388],[59,549],[141,218],[259,185],[-369,328]],[[13777,28830],[89,-183],[264,86],[251,-23],[268,-144],[410,-496],[223,-141],[206,269],[378,-358],[82,-218],[470,-238],[790,-323],[559,-310],[178,-182],[582,-289],[707,-464],[222,-201],[257,177],[93,-204],[428,89],[176,-273]],[[26873,14366],[-7,271],[258,-69],[1033,-791],[1165,-189],[856,-708],[-274,-200],[-214,240],[-338,-231],[115,-166],[371,-234],[66,-206],[334,-110],[-296,-126],[421,-157],[-76,-223]],[[23601,18738],[220,-139],[320,-346],[408,-135],[181,-253],[739,-684],[158,-39],[321,-277],[-171,13],[-224,-251],[71,-985],[63,-256],[-173,-736],[105,-11],[2,-310],[539,-1],[193,62],[520,-24]],[[28889,18731],[-342,437],[34,239],[-277,308],[-353,93],[-444,3],[-197,149],[-427,-169],[-168,-293],[-365,221],[-171,5],[-203,432],[-164,71],[-172,565],[52,246],[-228,-82],[-435,-551],[-238,186],[-445,195],[-337,-107],[-171,261]],[[35659,10895],[107,128],[362,81],[-37,336],[-334,58],[-279,130],[-44,460],[-408,223],[-400,73],[-323,137],[-334,636],[-538,384],[-217,624],[-241,466],[-276,416],[-278,307],[-644,319],[-271,311],[-161,26],[-473,274],[-624,741],[-176,408],[-821,630],[-64,376],[-296,292]],[[30287,11467],[390,-117],[167,108],[956,-47],[135,297],[706,-360],[89,-176],[252,-142],[599,20],[483,-199],[908,-15],[241,-239],[218,22],[228,276]],[[19468,24633],[454,382],[190,-3],[53,311],[245,81]],[[13777,28830],[-460,-129],[-348,3],[-37,-194],[-612,-496],[31,-537],[-459,-272],[95,-265],[148,-113],[-212,-559],[-128,-203],[94,-88]],[[21080,10688],[74,-249],[-47,-343],[486,-548],[98,-277]],[[20771,14273],[-173,-360],[186,-182],[245,-75],[176,-434],[536,-326],[77,-246],[180,-121],[-91,-274],[112,-17],[-157,-363],[-296,-260],[256,-376],[-207,-115],[33,-367],[-280,26],[-288,-95]],[[26873,14366],[210,-54],[-49,-346],[-866,-174],[-298,4],[-227,-294],[-461,101],[-57,-188],[291,-670],[-419,32],[-1169,462],[-220,353],[-520,404],[-448,-154],[-261,-10],[-361,121],[43,87],[-238,180],[-203,-184],[-221,11],[-191,136],[-437,90]],[[21691,9271],[636,217],[787,86],[591,-81],[236,69],[404,307],[-128,170],[351,-70],[333,114],[156,139],[307,-31],[76,192],[-40,534],[674,47],[598,-46],[298,-90],[518,15],[483,-52],[347,-184],[146,133],[-5,341],[96,383],[612,-280],[53,222],[482,236],[585,-175]],[[14900,11550],[-31,-236],[189,-174],[55,-199],[332,-4],[40,-112],[293,27],[152,-179],[-222,-50],[210,-113],[591,158],[605,-601],[161,-315],[894,121],[206,-236],[282,87],[56,-277],[327,-39],[221,-198],[-190,-214],[110,-179],[295,78],[165,206],[589,-255],[558,36],[67,-62],[836,451]],[[13452,15314],[73,-243],[-53,-236],[-151,-120],[151,-88],[-146,-211],[282,-174],[-181,-157],[350,-300],[408,-105],[-282,-294],[384,-273],[108,-194],[336,-333],[78,-339],[247,-367],[-228,-58],[72,-272]],[[21080,10688],[-84,487],[-393,210],[-156,-1],[-163,189],[-264,70],[-395,322],[-635,125],[-242,355],[-300,180],[79,97],[-267,60],[-186,697],[-318,260],[-736,-188],[-258,12],[-122,305],[-361,-73],[-545,755],[-294,23],[-271,-148],[-22,-182],[-311,371],[-231,501],[-249,-32],[-146,-249],[-187,376],[62,138],[-162,186],[-471,-220]],[[13452,15314],[-442,740]],[[9653,15292],[287,-252],[117,-227],[-288,-253],[-62,-151],[361,-365],[-40,-164],[135,-434],[-25,-321],[92,-537],[137,-478],[440,-177],[127,-434],[615,85],[587,217],[483,-135],[515,-76],[558,46],[325,248],[433,-477],[450,143]],[[13010,16054],[-79,-75],[-942,-201],[-151,202],[-170,-104],[-1048,-128],[-155,155],[-286,-106],[-75,157],[-416,-147],[127,-434],[-162,-81]],[[14425,19558],[-569,-112],[143,-502],[-849,-177],[-115,148],[-191,-72],[107,-260],[-447,-275],[233,-423],[-195,-166],[142,-175],[-188,-348],[829,-818],[-315,-324]],[[20771,14273],[196,127],[25,195],[-201,-40],[-199,250],[-188,-57],[-341,460],[79,57],[-287,269],[-544,165],[95,176],[473,62],[-106,162],[-459,170],[179,167],[212,-21],[86,143],[-253,251],[-627,242],[365,180],[416,110],[435,-93],[719,110],[440,-444],[0,-136],[471,-145],[449,176],[-217,366],[351,241],[335,385],[391,101],[221,228],[-123,305],[172,89],[30,204]],[[11476,21945],[10,-165],[179,-63],[163,-235],[39,-296],[-238,-407],[-354,73],[-301,156],[-164,295],[-111,-214],[-430,-178],[-362,-498],[-485,-120],[-359,15],[-2,-125],[-463,-55],[-400,-271],[-84,169],[-429,-199],[-98,25]],[[7587,19852],[-139,-470],[79,-305],[489,-457],[81,-319],[-267,-617],[-3,-277],[218,-335],[529,-426],[442,-480],[299,-177],[174,-250],[164,-447]],[[9612,24631],[-292,-122],[-1017,-121],[-443,-119],[80,-183],[-400,-242],[-678,-306],[-726,556],[-195,19],[-448,-191],[401,-479],[323,-750],[238,-853],[322,-394],[696,-530],[229,-297],[11,-349],[-126,-418]],[[24660,23595],[-43,498],[90,201],[-172,231],[-65,353],[253,-12],[-267,304],[89,193],[-262,198],[-89,301],[48,152],[278,142],[30,278],[-149,145],[-154,401],[405,418],[60,208],[-424,321],[-213,333],[-4,421],[-195,404],[-142,115],[-39,334],[-118,221]],[[24260,23328],[400,267]],[[18105,34929],[284,-198],[309,-390],[202,-35],[390,-450],[460,-433],[221,-299],[413,-319],[-240,-112],[47,-358],[276,-474],[-118,-263],[169,97],[210,-56],[-94,-366],[-176,-89],[-31,-526],[59,-271]],[[18978,35969],[-160,-104],[-87,-289],[-255,-76],[-175,73],[-241,-259],[223,-188],[-178,-197]],[[20907,35797],[-289,31],[-849,339],[-541,-270],[-250,72]],[[23577,29755],[-266,197],[-150,278],[51,593],[137,318],[-195,399],[48,526],[179,196],[-113,262],[74,247],[-67,171],[-465,460],[-96,327],[-185,191],[173,394],[-288,340],[-562,331],[-319,443],[-140,-22],[-486,391]],[[18105,34929],[-259,148],[-1000,200],[-181,-82],[-358,49],[-41,-298],[-338,-217],[55,-231],[-88,-239],[265,-359],[396,-94],[-35,-214],[190,-424],[58,-491],[171,-235],[-362,-66],[-58,138],[-593,-110]],[[43807,90467],[203,-288],[281,-36],[587,-222],[138,733],[358,-452],[250,264],[587,22],[560,-591]],[[43523,91058],[-67,-194],[351,-397]],[[43088,93509],[-1,-51],[911,-168],[-198,-308],[295,-144],[-181,-183],[-58,-430],[-180,-536],[74,-381],[-227,-250]],[[48808,94841],[-1663,87],[-205,-111],[-298,38],[-435,-120],[-17,-414],[-331,-202],[-243,-55],[-238,92],[-375,-101],[-609,-262],[76,-136],[-636,258],[-399,-142],[20,-214],[-367,-50]],[[46771,89897],[230,123],[-218,314],[508,352],[244,-405],[507,249],[-332,407],[343,241],[558,195],[-258,115],[-99,349],[74,120],[473,-47],[146,99],[-51,403],[190,159],[-389,-50],[-155,363],[150,119],[-12,542],[225,278],[-82,137],[176,532],[-191,349]],[[40125,76310],[-533,7],[-443,243],[-740,493],[-297,-68],[-408,30],[-41,-78],[-523,242],[-552,65],[-262,-60],[-684,66],[-968,138],[-612,21],[-210,-89],[-211,87]],[[40808,76060],[-416,207],[-267,43]],[[37703,72418],[989,59],[181,71],[112,-130],[271,15],[194,-111],[192,366],[-16,184],[612,809],[-333,133],[103,429],[-137,31],[62,324],[183,-43],[-108,213],[-247,182],[261,246],[226,45],[216,214],[62,210],[282,395]],[[32970,75189],[374,-22],[253,-151],[530,-61],[556,-373],[9,-542],[-227,-178],[261,-86],[970,150],[408,-52],[303,-293],[876,-518],[83,-263],[337,-382]],[[33641,77407],[-278,-533],[-70,-270],[-74,-728],[-249,-687]],[[40145,70180],[504,-27],[348,105],[373,263],[197,40],[209,-239],[240,37],[186,-235],[394,-340],[449,-215],[-207,-237],[309,-78],[-24,-179],[-231,-196],[284,-84],[250,37],[328,-159]],[[37703,72418],[178,-272],[-209,-85],[556,-843],[-108,-244],[385,17],[993,-205],[155,-346],[259,-223],[233,-37]],[[43003,75805],[-357,38],[-603,-34],[-458,266],[-71,-82],[-706,67]],[[45805,74547],[-432,336],[-246,-52],[-397,175],[-224,-39],[40,-151],[-442,1],[-216,148],[-80,378],[-402,74],[7,237],[-410,151]],[[43754,68673],[-262,258],[174,119],[381,464],[126,-151],[241,246],[425,159],[-119,402],[277,125],[-89,194],[291,26],[78,229],[231,-43],[362,66],[-120,84],[567,430],[218,242],[-157,175],[-533,133],[-384,191],[-37,420],[648,-298],[-189,539],[150,297],[-173,427],[-382,427],[454,183],[186,-50],[35,197],[-174,301],[-174,82]],[[40048,93791],[684,-357],[459,-292],[894,-726],[201,-246],[64,-577],[-91,-248]],[[43088,93509],[-968,340],[-249,392],[-105,385],[-442,697],[-73,505],[-420,-120],[37,-186],[-482,-38],[-32,228],[-204,-29],[-138,115],[-441,169],[-22,-564],[-155,30],[-87,-275],[-191,11],[-10,-305],[176,-499],[438,-386],[328,-188]],[[42259,91345],[497,-196],[767,-91]],[[45778,79775],[9,-256],[-450,-61],[-356,-123],[-77,-256],[138,-2],[57,-243],[-442,-241],[-589,5],[6,-514],[-90,-352],[-190,-414],[32,-283],[-333,-61],[60,-214],[231,-234],[-354,-52],[278,-158],[-405,-45],[6,-135],[-309,-17],[3,-314]],[[48759,75426],[-7,207],[-234,108],[-117,280],[-225,-42],[-76,253],[-130,-27],[-138,352],[246,-40],[332,328],[30,159],[-427,347],[116,67],[162,351],[-426,641],[-505,152],[-172,163],[63,323],[-114,265],[-22,316],[238,238],[-157,176],[-507,-206],[-21,126],[-239,10],[-651,-198]],[[48755,75278],[4,148]],[[45805,74547],[161,106],[437,-99],[148,-144],[390,19],[5,379],[187,40],[70,-216],[406,283],[-123,259],[240,120],[417,-133],[288,169],[324,-52]],[[47185,96943],[444,171],[190,1],[619,-214]],[[42736,99580],[131,-381],[428,-367],[158,59],[570,-70],[-159,-291],[-236,-79],[309,-209],[689,-218],[526,-334],[897,-458],[631,-234],[505,-55]],[[48438,96901],[231,747],[-55,606],[-952,162],[-41,-91],[-673,237],[-815,464],[-445,329],[-802,491],[-428,133],[-306,8],[-620,-249],[-796,-158]],[[40998,82022],[-257,-166],[-939,-47],[-421,-95],[-243,-216],[-1364,439],[-677,-688],[-227,166]],[[44313,80718],[-415,138],[-1,179],[-159,187],[-640,-33],[-467,-137],[-266,237],[-397,-6],[-182,78],[26,215],[-315,326],[-499,120]],[[44585,79980],[133,181],[-303,48],[-102,509]],[[40125,76310],[359,134],[-11,598],[740,18],[60,211],[-245,168],[234,246],[91,531],[-224,41],[208,145],[47,175],[285,18],[-27,425],[491,4],[101,369],[228,-4],[34,419],[330,-163],[91,136],[281,-48],[850,81],[537,166]],[[36870,81415],[-1201,-338],[-510,-256],[-283,-235],[-339,-465],[-122,-385],[-7,-320],[88,-384],[377,-776],[4,-384],[-242,-139],[-499,-66],[-331,-117],[-164,-143]],[[41482,96573],[384,-245],[305,181],[245,-15],[383,219],[256,-133],[146,180],[332,139],[260,-354],[514,151],[449,-125],[442,67],[615,-82],[259,-82],[4,232],[466,58],[643,179]],[[42736,99580],[-671,-81],[-359,-133],[-97,77],[-139,-171],[-14,-238],[544,-1788],[-211,-467],[-307,-206]],[[53703,76306],[-189,60],[-375,495],[-338,-191],[-224,-29],[-39,166],[-644,-36],[-53,84],[-627,-204],[-80,312],[-568,-149],[-367,3],[-348,178],[-168,-376],[327,-120],[-323,-222],[213,-68],[-162,-151],[-127,73],[-138,-200],[-297,131],[-89,-644],[-328,8]],[[53573,75445],[182,169],[-74,207],[329,67],[-133,324],[-174,94]],[[51964,73525],[103,139],[276,51],[-183,372],[409,544],[391,-4],[8,213],[-179,173],[-3,195],[-178,220],[302,177],[420,45],[243,-205]],[[48755,75278],[48,-220],[251,-152],[339,-35],[280,113],[130,-269],[321,-245],[213,100],[130,-330],[-240,-218],[298,-124],[249,-450],[-42,-298],[178,-13],[448,285],[42,245],[314,-3],[250,-139]],[[48437,87865],[-81,-553],[64,-575],[208,-20],[27,-149],[-284,-2],[-23,-214],[192,-44],[29,-833],[-86,-9],[41,-445],[-351,-431],[-508,-294],[-670,-139],[-322,-18],[-721,-307],[-291,-41],[-432,-162],[-258,-209],[-333,-102],[-111,-462],[-264,-71],[78,-211],[-143,-350],[-1024,-62],[-414,64],[-48,-195],[-441,23],[-1273,-32]],[[51833,87471],[-480,105],[-245,183],[59,67],[-430,175],[-158,-181],[-290,213],[-409,-54],[-820,-14],[-186,-127],[-437,27]],[[53390,81942],[53,137],[296,10],[-123,326],[402,-19],[50,505],[-341,-56],[-230,60],[-40,310],[209,319],[412,239],[321,440],[-106,382],[-175,280],[-607,149],[-308,134],[-599,-277],[-220,282],[-452,217],[178,477],[79,840],[-643,88],[48,480],[329,-45],[-90,251]],[[44313,80718],[1024,-433],[469,-101],[243,209],[4,663],[96,438],[276,387],[681,693],[326,774],[399,343],[403,93],[257,-16],[539,-215],[383,-338],[383,-585],[363,-392],[569,-339],[479,-140],[675,18],[557,184],[353,50],[598,-69]],[[49950,94714],[196,-1],[53,173],[-55,336],[-180,-29],[-109,577],[-200,155],[-324,92],[-708,355],[-208,436],[23,93]],[[48808,94841],[302,7],[840,-134]],[[41482,96573],[-541,-218],[-410,43],[-351,456],[-280,126],[-459,-495],[-202,-749],[-247,109],[-294,-654],[130,-497],[309,-566],[644,-481],[267,144]],[[43807,90467],[-160,-79],[285,-220],[23,-157],[223,-215],[169,-290],[-389,-239],[-484,-490],[-292,-64],[-373,90],[-11,113],[-374,34],[-142,-315],[-298,-310],[-348,-49],[-428,-237],[-112,-270],[557,-307],[450,-186],[507,-332],[-101,-278],[57,-262],[-1028,-693],[-235,-190],[-483,-48],[-447,-135],[217,-195],[215,-433],[775,166],[84,-213],[-52,-236],[-373,-193],[-262,-293],[-262,-176],[461,-466],[-872,-494],[-1079,-100],[-170,126],[-6,304],[436,212],[-19,365],[-513,-113],[-128,295],[-359,420]],[[48437,87865],[-743,384],[401,178],[148,-134],[194,164],[-228,239],[-645,475],[-793,726]],[[38466,84314],[-526,-494],[-546,-379],[-193,-329],[-133,-732],[128,-453],[-37,-230],[-289,-282]],[[57904,81777],[616,143],[377,-55],[184,-199],[18,-531],[155,-354],[512,-429],[500,-73],[313,194],[239,314],[268,221],[302,100]],[[53390,81942],[526,-289],[450,-20],[521,516],[441,231],[492,142],[384,343],[90,352],[264,198],[315,-47],[325,-268],[410,-449],[87,-193],[-73,-230],[-271,-161],[-606,-135],[-197,-124],[-32,-191],[259,-199],[362,29],[767,330]],[[55615,88868],[-1,87],[-895,-70],[-73,-65],[-367,98],[-393,-230],[-171,-28],[62,-175],[-63,-515],[39,-270],[405,-57],[104,-250],[-100,-284],[-582,154],[-245,261],[-408,160],[-521,-19],[-573,-194]],[[60674,87697],[-351,102],[-76,-476],[-534,137],[-295,-455],[-363,120],[-114,-219],[-449,-51],[40,-160],[-165,-118],[-495,-26],[-446,45],[-72,276],[-516,-69],[41,398],[-497,94],[103,544],[-286,125],[-798,73],[216,615],[-2,216]],[[61484,86533],[345,71],[340,208],[-91,185],[216,-12],[-207,561],[-254,280],[-350,1],[-86,-179],[-428,157],[-112,-147],[-183,39]],[[61388,81108],[-193,669],[-225,76],[261,256],[98,366],[117,80],[-392,52],[45,107],[-506,364],[-219,319],[-31,509],[-408,125],[97,704],[401,17],[63,212],[431,-2],[-40,684],[123,261],[-100,592],[343,356],[231,-322]],[[42259,91345],[-435,-932],[-315,-465],[-225,-195],[-541,-288],[-451,-133],[-1206,-138],[-512,125],[-206,201],[-7,303],[267,215],[502,-10],[396,73],[258,146],[209,268],[52,250],[-116,556],[-180,293],[-498,366],[-519,80],[-159,-104],[-213,-331],[-99,-428],[-235,-388],[-568,-275],[-263,-196],[-111,-365],[34,-307],[204,-692],[63,-1013],[207,-711],[238,-552],[291,-475],[483,-660],[123,-308],[-15,-469],[-246,-472]],[[63552,81240],[-1153,-26],[-1011,-106]],[[64701,76422],[-20,461],[-500,241],[21,682],[-444,107],[-37,280],[153,464],[220,203],[-294,1193],[3,407],[-165,230],[-151,-19],[65,569]],[[60502,77045],[135,232],[-114,236],[340,30],[173,152],[366,-326],[247,243],[93,207],[374,-313],[42,-358],[179,35],[35,-161],[550,91],[-14,-269],[520,-80],[228,-285],[471,-60],[574,3]],[[59266,77940],[804,-473],[432,-422]],[[57904,81777],[36,-378],[-123,-534],[-383,104],[-60,-463],[-553,-183],[-108,-201],[286,-360],[409,-164],[-55,-183],[224,-34],[517,-377],[-86,-93],[435,-120],[263,-410],[560,-441]],[[56308,90301],[-154,252],[-243,-18],[-92,240],[-455,-134],[-368,-331],[-834,387],[-142,184],[-297,122],[-95,239],[-266,-6],[-51,130],[-854,112],[-413,193],[-372,107],[27,230],[-247,428],[-329,-35],[-7,328],[-234,95],[-158,328],[-275,128],[-192,280],[50,212],[-309,333],[-48,609]],[[55615,88868],[443,-89],[-122,352],[92,135],[463,-64],[-304,294],[-95,245],[453,30],[-237,530]],[[60674,87697],[88,646],[357,289],[-493,408],[474,494],[-54,237]],[[61046,89771],[-297,145],[-312,57],[-42,445],[53,161],[-429,-161],[-423,-64],[-282,81],[-213,-217],[-679,193],[-162,104],[-785,34],[-178,-227],[-502,1],[-38,-149],[-449,127]],[[45778,79775],[-386,68],[-730,-123],[-77,260]],[[26154,62963],[362,-195],[538,-125],[-104,-864],[589,-384],[-21,-47],[669,-314],[617,90]],[[26043,63227],[111,-264]],[[32976,65570],[-181,180],[-140,-153],[-388,-148],[-79,211],[-514,151],[-43,465],[-311,-75],[-27,-149],[-239,-15],[-527,-272],[-172,-355],[-145,-109],[-635,-231],[-583,-358],[-67,19],[-1047,-512],[-219,-144],[-1616,-848]],[[28804,61124],[-40,184],[-294,535],[-145,479],[242,257],[163,-252],[395,321],[649,305],[164,207],[423,-224],[213,176],[177,-36],[1199,127],[380,266],[177,52],[8,385],[130,64],[398,-112],[43,209],[-268,99],[-126,179],[-141,450],[-298,339],[131,133],[512,-78],[292,-123],[129,121],[-341,383]],[[42527,55786],[-403,-76],[-59,233],[-408,129],[-113,-127],[-239,137],[-305,-262],[40,-175],[-353,-171],[-229,149],[-172,-201],[-196,-448],[-308,-262],[-321,-117],[156,-143],[-138,-581],[178,-58],[-221,-390],[207,-77],[-148,-475],[-218,-190],[-268,-496]],[[47804,51609],[-96,-81],[-498,171],[-260,195],[-637,171],[-134,250],[-370,403],[-353,181],[-215,309],[-407,247],[-71,424],[-599,540],[208,228],[-141,131],[-128,-221],[-133,32],[-291,305],[-267,-99],[-530,734],[-221,-94],[-134,351]],[[47839,48768],[249,138],[210,358],[-300,90],[87,255],[-277,-6],[-299,161],[-119,349],[227,549],[-102,190],[-1,312],[559,-72],[-8,226],[-261,291]],[[43037,50486],[257,158],[377,20],[137,-676],[495,77],[21,-170],[623,-15],[374,-94],[49,-113],[625,-129],[908,-642],[211,-32],[230,165],[126,-178],[369,-89]],[[39009,52185],[577,-384],[463,-436],[656,-54],[544,-93],[120,-93],[310,268],[253,94],[277,-236],[514,62],[73,-447],[194,-6],[59,-162],[-140,-87],[128,-125]],[[30381,72885],[-310,278],[-570,176],[-515,357],[-219,260],[-669,376],[-344,362],[-431,58],[-254,176],[-394,-141]],[[34341,66966],[-287,434],[-411,124],[30,142],[-492,151],[-436,-216],[-316,415],[-289,88],[281,436],[-11,286],[-233,233],[177,134],[-21,159],[-392,496],[-357,215],[-161,204],[-192,512],[-731,378],[46,1063],[-207,466],[42,199]],[[33614,65293],[214,160],[378,59],[158,332],[-4,200],[-242,364],[-85,424],[308,134]],[[32976,65570],[318,88],[320,-365]],[[25650,65652],[314,-529],[-285,-141],[-307,-29],[-373,-181],[-91,-252],[542,-446],[-93,-599],[686,-248]],[[25042,71704],[260,-367],[388,-216],[102,-295],[-107,-270],[323,-373],[67,-391],[-240,-507],[-177,-234],[-260,-696],[-16,-472],[353,-179],[514,-55],[-11,-169],[368,-251],[-133,-531],[-483,-248],[80,-236],[-328,-308],[-92,-254]],[[26675,74787],[216,-1365],[62,-900],[-473,267],[-283,4],[-154,-101],[-85,-377],[-205,-385],[-452,-65],[-259,-161]],[[43226,46509],[-100,233],[17,290],[-290,444],[-475,895],[31,603],[-227,-5],[-113,423],[262,202],[-131,247],[324,71],[-67,351],[580,223]],[[41627,46254],[26,-224],[726,127],[847,352]],[[37932,51560],[851,-165],[119,-287],[-157,-527],[317,-371],[74,-362],[340,-30],[-419,-463],[620,-430],[350,-391],[-3,-352],[362,143],[128,-227],[-153,-96],[413,-496],[234,-457],[143,86],[290,-552],[273,-58],[-87,-271]],[[39009,52185],[-405,-351],[-266,183],[-243,39],[-163,-496]],[[19713,77759],[-365,-148],[-156,-196],[328,50],[247,-222],[446,-83],[283,156],[1002,18],[17,68],[704,58],[138,-122],[-169,-341],[-35,-322],[438,2],[291,226],[178,-61],[357,-318],[400,-184],[279,-54],[11,357],[366,-108],[220,-148],[224,122],[212,-273],[-69,-428],[195,-67],[-199,-318],[154,-287],[-133,-214],[309,-220],[143,-411],[354,-27],[-131,320],[477,95],[430,304],[16,-196]],[[20262,77911],[-549,-152]],[[22231,78492],[401,-133],[-133,-455],[-1286,-189],[-885,-17],[-66,213]],[[24602,80865],[-10,-269],[-200,-380],[575,-458],[118,-315],[19,-479],[-255,-275],[-79,74],[-231,-255],[-676,62],[-264,-130],[-586,195],[-153,-97],[-552,140],[-77,-186]],[[29195,80843],[-390,-175],[-309,-377],[-724,-496],[-433,183],[-692,570],[-296,388],[-858,-8],[-308,65],[-583,-128]],[[29749,80798],[-280,245],[-274,-200]],[[30880,73411],[-496,530],[-112,690],[-146,497],[-197,371],[-495,592],[-582,429],[439,237],[286,30],[91,193],[-177,112],[104,229],[-304,143],[-277,-79],[-347,38],[-186,-71],[-673,148],[-12,106],[298,193],[93,217],[366,-55],[42,105],[-561,254],[-114,-29],[-32,255],[-344,247],[120,145],[419,100],[-128,201],[-145,485],[265,51],[365,258],[248,254],[1061,511]],[[30889,72911],[-9,500]],[[30381,72885],[508,26]],[[38585,62136],[198,13],[378,237],[338,285],[936,156],[73,258],[462,263],[346,65],[505,-126],[272,352],[518,-86],[233,-99],[43,250],[-113,542],[94,39],[299,-215],[-51,648]],[[34178,61941],[374,82],[500,-69],[257,-146],[-45,196],[342,-48],[238,175],[324,356],[279,423],[188,-298],[587,-215],[302,25],[117,-81],[418,82],[37,-155],[332,205],[157,-337]],[[33614,65293],[324,-516],[-10,-154],[-277,-110],[-61,-138],[139,-163],[-178,-67],[260,-429],[-313,-161],[-231,-474],[468,-354],[270,-56],[-98,-353],[271,-377]],[[36123,68813],[153,-160],[-188,-141],[-184,20],[113,-257],[-436,128],[-179,-125],[89,-426],[-342,-102],[144,-246],[22,-239],[-859,-374],[-115,75]],[[39206,67884],[-284,-31],[-39,-207],[-228,-98],[-137,77],[-343,442],[-157,38],[-543,-113],[-129,544],[-508,465],[-203,49],[-512,-237]],[[41080,67586],[-892,373],[-246,-285],[-337,-8],[-399,218]],[[43116,64718],[-49,135],[-358,304],[-163,-61],[82,490],[-267,29],[-105,163],[-295,17],[-13,190],[-602,228],[640,447],[189,296],[-393,142],[-135,181],[-473,161],[-94,146]],[[32970,75189],[-935,-1343],[-357,-431],[-275,-139],[-251,-6],[-272,141]],[[39206,67884],[85,251],[165,25],[-44,169],[216,4],[334,202],[-15,138],[-538,55],[469,903],[169,137],[98,412]],[[30889,72911],[110,-122],[599,-384],[478,30],[181,-97],[16,-619],[237,-26],[391,131],[690,66],[110,-386],[258,-379],[1012,-773],[314,-354],[-60,-746],[-130,-96],[312,-276],[529,-129],[187,62]],[[22402,71391],[111,-327],[189,-307],[84,37],[174,-270],[618,685],[474,284],[566,205],[181,-117],[243,123]],[[15393,74184],[683,-450],[169,198],[607,-13],[97,268],[220,3],[58,181],[571,144],[310,-426],[-94,-226],[888,-267],[80,61],[937,-548],[248,11],[669,-251],[145,-221],[255,-140],[34,-152],[714,-407],[270,-261],[148,-297]],[[16622,76812],[409,-765],[342,-560],[-76,-140],[-617,-582],[-484,-151],[-431,-304],[-372,-126]],[[19713,77759],[-639,158],[-253,17],[-406,-134],[-715,-479],[-545,-310],[-533,-199]],[[22231,78492],[-401,60],[-410,-36]],[[21420,78516],[-579,-238],[-579,-367]],[[21405,67259],[202,65],[276,-121],[418,-467],[572,294],[270,-354],[279,129],[181,-202],[-239,-113],[68,-200],[-114,-66],[254,-343],[495,107],[312,-65],[261,43],[210,-133],[496,207],[304,-388]],[[20901,68581],[214,-343],[99,-363],[214,-414],[-23,-202]],[[22402,71391],[-789,-390],[314,-998],[-202,-192],[-145,-291],[-213,-205],[-438,-244],[-28,-490]],[[25557,62604],[373,155],[224,204]],[[20445,62944],[242,150],[792,237],[75,167],[270,162],[-1,-267],[403,-4],[14,118],[361,-102],[559,-74],[721,96],[280,148],[124,-62],[286,-516],[558,-572],[428,179]],[[21405,67259],[-155,-96],[89,-123],[-256,-207],[310,-140],[-208,-131],[-424,-484],[204,-184],[16,-240],[-243,-515],[-1221,-484],[289,-298],[639,-1413]],[[20221,79697],[224,79],[266,-259],[611,-776],[98,-225]],[[19787,82948],[-400,-448],[-184,-88],[-247,-360],[12,-472],[182,-333],[172,-575],[80,43],[431,-715],[312,56],[76,-359]],[[24602,80865],[-319,506],[-805,242],[-369,-27],[-176,118],[-376,-60],[-179,82],[-393,3],[-282,489],[-258,174],[-173,575],[101,94],[-485,17],[-269,-348],[-465,25],[-367,193]],[[31340,52329],[476,311],[345,-242],[84,-278],[375,17],[250,261],[504,-28],[341,193],[29,-419],[367,72],[236,193],[274,-190],[64,112],[325,-147],[697,-190],[107,175],[351,-98],[329,29],[390,-142],[180,-174],[272,-81],[58,-171]],[[31206,57243],[-506,-640],[-902,-1567],[442,-111],[117,-205],[-416,-1081],[1399,-1310]],[[35120,59790],[-239,63],[-349,-350],[1,-145],[-223,-313],[220,-284],[-223,-212],[-947,37],[52,-111],[-232,-126],[-124,88],[-510,73],[-242,130],[-227,265],[-216,-106],[280,-537],[476,-560],[-1018,-790],[-393,331]],[[40061,60075],[-130,-327],[-469,-428],[-405,-209],[220,-217],[138,-756],[-515,-22],[-125,-539],[-116,-38],[-83,380],[-533,-555],[-211,138],[156,169],[-292,523],[-395,75],[1,306],[-713,187],[-342,300],[66,109],[-433,323],[-306,7],[-155,180],[-299,109]],[[42375,58790],[-408,44],[-637,-155],[-213,-229],[-175,681],[165,455],[-73,108],[-232,-79],[-324,209],[-394,-21],[-23,272]],[[42527,55786],[418,160],[57,181],[-226,103],[87,108],[-289,113],[148,108],[-79,242],[251,114],[50,141],[-367,244],[-179,340],[49,232],[-92,390],[-155,197],[274,180],[-99,151]],[[37394,51532],[538,28]],[[34178,61941],[-241,-524],[274,-223],[126,-212],[73,-460],[93,35],[224,-392],[312,-27],[166,-199],[-85,-149]],[[40061,60075],[145,381],[-736,754],[-113,45],[255,334],[-720,353],[-307,194]],[[46758,58273],[-173,174],[-316,-123],[-252,-214],[-164,182],[-313,36],[-143,180],[-385,-214],[-402,213],[47,327],[-158,329],[-217,186],[-168,-31],[-211,359],[-989,-407],[-295,-10],[-243,-318],[-1,-152]],[[50029,56326],[-354,100],[-324,362],[-472,-198],[-72,169],[-375,387],[-1145,686],[-318,11],[-266,353],[55,77]],[[47804,51609],[141,175],[200,-30],[100,475],[-180,123],[173,111],[-114,302],[253,-26],[167,98],[-238,374],[65,169],[233,116],[-141,419],[212,90],[150,-223],[519,359],[377,86],[106,-79],[498,221],[622,574],[-67,169],[-457,342],[-115,471],[108,31],[-245,235],[-183,-144],[-121,96],[162,183]],[[47544,63182],[-406,36],[-138,214],[135,188],[-657,214],[-257,-282],[-331,-25],[-363,239],[-474,96],[-132,-91],[-505,8],[-312,214],[8,443],[130,430],[-74,178],[-288,164],[-232,9],[-270,-163],[-6,-403],[-256,67]],[[47911,61839],[86,169],[-55,417],[-260,42],[129,252],[-308,76],[41,387]],[[46758,58273],[124,347],[233,20],[84,295],[-213,161],[86,370],[-325,256],[-54,268],[392,241],[-259,178],[48,212],[-239,-20],[2,501],[593,-25],[32,286],[178,182],[267,11],[204,283]],[[34424,48546],[-8,481],[130,116],[370,-68],[271,194],[214,-133],[283,66],[570,-76],[264,160],[271,48],[-256,386],[669,543],[347,-68],[43,148],[-434,102],[404,902],[-168,185]],[[31488,50500],[250,-824],[159,-129],[-91,-271],[-469,-622],[1058,-479],[74,22],[174,-366],[143,-124],[681,189],[290,498],[443,-58],[224,210]],[[31340,52329],[-56,-38],[419,-817],[347,-218],[-582,-550],[20,-206]],[[24696,88094],[417,-238],[59,-505],[244,-385],[262,-79],[235,-197],[-411,-888],[202,-137],[-135,-875],[174,-320],[248,-73],[-59,-151],[461,-880],[152,-383],[342,-471],[231,67],[131,-288],[170,49],[400,-402],[-64,-47],[470,-280],[388,-165],[582,-603]],[[29749,80798],[427,-85],[382,134],[372,210],[93,148],[-14,352],[707,467],[429,56],[-231,344],[349,296],[386,608],[-16,705],[566,186],[436,12],[241,151],[12,120],[-501,31],[-168,448],[68,69],[-214,361],[-1009,-105],[-270,765],[-224,57],[-326,619],[-832,49],[-335,106],[-330,-52],[-127,68],[-518,-65],[-228,353],[-664,-150],[88,381],[-64,493],[-337,-18],[-655,97],[-149,87],[-961,-49],[-600,308],[-175,171],[-552,-19],[-253,-89],[144,-324]],[[38190,45966],[335,-55],[478,-374],[370,145],[275,-100],[71,85],[-152,202],[240,57],[66,196],[370,-182],[94,211],[660,262],[19,-182],[171,125],[440,-102]],[[34424,48546],[-30,-548],[79,-723],[-191,-219],[104,-132],[2357,-608],[141,-74],[1211,-183],[95,-93]],[[19787,82948],[-842,857],[-288,224]],[[18657,84029],[-430,-555],[-182,132],[-479,31],[-112,-63],[208,-240],[-215,-297],[-301,-10],[68,-286],[-327,-174],[-441,-133],[-694,-47],[-403,45],[-16,-449],[85,-473],[172,-71],[306,-366],[199,-438],[-82,-314],[-15,-489],[328,16],[15,-82],[334,4],[334,-700],[228,-60],[320,138],[807,-11],[645,160],[234,-24],[349,324],[629,100]],[[24696,88094],[-195,-143],[-35,-331],[136,-190],[-148,-55],[72,-204],[-204,-158],[-81,92],[-101,-350],[348,-64],[15,-220],[-669,-26],[-546,94],[133,-327],[-25,-420],[148,-234],[-273,-58],[180,-137],[-421,-82],[-406,26],[-344,-153],[-1189,-394],[-768,108],[-219,-135],[-388,70],[-205,-203],[-649,281],[-188,-311],[108,-257],[-125,-284]],[[30705,57665],[501,-422]],[[28804,61124],[291,-415],[-117,-253],[405,-575],[71,-258],[448,-487],[-495,-378],[1298,-1093]],[[9314,71815],[-743,61],[-23,-103],[-338,-43],[-266,-304],[-171,-59],[-132,-370],[-258,45],[155,-279],[-45,-134],[-257,-79],[-4,-197],[-490,342],[52,-351],[139,-107],[327,-462],[-52,-307],[-201,-41]],[[13010,70395],[-352,145],[-185,-223],[-396,-111],[-1032,952],[-325,100],[-669,615],[-332,-128],[-405,70]],[[16367,66134],[-201,178],[-236,375],[-487,-28],[-160,88],[-137,254],[-141,-54],[-281,678],[-33,365],[165,76],[-824,665],[-639,832],[74,120],[308,128],[-865,273],[100,311]],[[15253,65374],[347,302],[182,-150],[585,608]],[[10253,66675],[196,-297],[386,-275],[-105,-218],[619,-388],[256,269],[183,-45],[331,84],[268,-159],[184,216],[460,-268],[95,427],[87,77],[193,-150],[620,173],[177,-198],[5,-305],[235,-148],[265,57],[556,8],[-11,-161]],[[9591,67557],[662,-882]],[[7007,69427],[-285,-694],[65,-56],[633,-103],[238,-244],[379,240],[395,-315],[396,-77],[512,-222],[251,-399]],[[7424,59849],[-321,-31],[-988,24],[-420,-46]],[[10029,57583],[65,244],[-79,150],[-293,82],[-458,-69],[189,350],[253,226],[-48,399],[-292,125],[-154,585],[-634,62],[-520,6],[-634,106]],[[9759,55361],[249,1253],[-15,721],[36,248]],[[5695,59796],[-276,-514],[202,-91],[458,-44],[-136,-159],[-212,-551],[-354,36],[-91,-475],[-137,-42],[-53,-219],[702,-88],[63,-460],[410,-113],[-15,-137],[472,-73],[400,55],[-333,-322],[136,-108],[590,113],[120,-347],[654,189],[328,-178],[276,-442],[258,-304],[393,-159],[209,-2]],[[16632,56166],[-472,-56],[-81,222],[165,-18],[24,594],[-192,82],[-300,-71],[-464,-350],[-51,168],[-359,166],[17,333],[-294,-30],[-632,-158],[-65,160],[-471,-84],[-33,144],[-759,-32],[-271,-161],[-297,24],[-255,141],[-837,176]],[[16895,55723],[-51,321],[-120,-67],[-92,189]],[[13297,53560],[587,-61],[-87,604],[825,264],[-82,301],[424,-63],[703,-38],[32,631],[745,95],[53,193],[405,118],[-7,119]],[[9953,53827],[839,-15],[14,-51],[602,77],[24,-51],[1814,-123],[51,-104]],[[9531,54016],[-142,-125],[580,71],[-16,-135]],[[9759,55361],[-51,-103],[-584,49],[-145,60],[-153,-192],[533,-68],[-37,-348],[-257,17],[-14,-108],[551,-47],[83,-304],[220,-26],[-374,-275]],[[11005,57416],[-559,-41],[-417,208]],[[9953,53827],[-61,-575],[-97,-234],[-516,127],[-40,-178],[235,-71],[-241,-159],[96,-87],[-33,-450],[138,-37],[-147,-480],[381,-136],[-257,-552]],[[13942,49863],[184,297],[481,513],[438,881],[-511,141],[102,249],[-552,262],[57,343],[-614,81],[47,628],[-165,32],[-112,270]],[[9748,50930],[769,-224],[452,-191],[1127,-225],[459,-169],[643,-126],[239,42],[505,-174]],[[9411,50995],[337,-65]],[[9531,54016],[-2421,281],[-15,-196],[-753,71],[-767,-43],[-351,-140]],[[7444,51416],[535,-154],[721,-11],[711,-256]],[[5224,53989],[353,-40],[-80,-364],[94,-28],[91,-601],[465,54],[64,-170],[-426,-47],[40,-500],[244,-108],[-28,-223],[610,81],[-15,-161],[217,-47],[591,-419]],[[14160,60326],[-126,-43],[-57,-474],[-118,-52],[106,-223],[-329,-77],[-370,94],[150,-431],[-266,14],[51,-196],[-141,-14],[-156,-493],[-119,87],[-80,568],[-597,-199],[-193,-451],[-416,-479],[-236,-174],[-358,-108],[100,-259]],[[18686,61367],[-87,-50],[-747,47],[-738,-144],[-811,68],[-155,-245],[-548,180],[-521,-434],[-919,-463]],[[16632,56166],[-38,298],[165,102],[52,465],[-112,216],[361,58],[255,169],[-22,161],[160,175],[11,597],[565,18],[-2,159],[-205,538],[56,297],[254,389],[502,1006],[-63,18],[115,535]],[[5224,53989],[-457,-228]],[[4340,51010],[415,123],[316,-129],[85,65],[517,13],[236,-60],[102,107],[494,-15],[192,-90],[108,264],[236,206],[383,-206],[20,128]],[[4767,53761],[-811,-177],[71,-414],[-182,-22],[111,-415],[55,-683],[293,-107],[110,-282],[-64,-219],[160,-238],[-170,-194]],[[20901,68581],[-268,-931],[-464,101],[-14,-106],[-286,-86],[-615,107],[-2031,-363],[36,-368],[-325,-71],[-361,-513],[-206,-217]],[[18985,62108],[448,245],[196,358],[816,233]],[[15253,65374],[-44,-372],[908,-7],[-207,-445],[168,-292],[155,-61],[132,202],[533,-123],[102,-367],[-173,-142],[285,-302],[-90,-35],[165,-253],[84,-402],[-618,-265],[392,-293],[994,-115],[776,48],[170,-42]],[[18985,62108],[-226,-151],[-73,-276]],[[22668,60175],[165,199],[402,-62],[84,445],[448,-116],[92,380],[542,571],[528,220],[-43,60],[458,260],[118,-171],[415,225],[-320,418]],[[18686,61681],[280,-49],[262,-581],[407,10],[-101,399],[274,157],[128,-74],[471,428],[199,-504],[329,-3],[123,-317],[123,-85],[213,146],[507,-41],[-29,-227],[116,-430],[72,-16],[209,-429],[399,110]],[[18686,61681],[0,-314]],[[26439,56690],[-224,1175],[-62,103],[-745,-431],[174,-502],[-437,-179],[-307,-196],[-35,225],[-325,352],[-495,-91],[-379,733],[134,8],[-133,214],[-147,-13],[-195,230],[312,-55],[-110,314],[-350,108],[-160,467],[-645,222],[358,801]],[[22723,53197],[430,822],[402,3],[238,165],[367,64],[-123,197],[438,137],[-264,214],[232,84],[-111,246],[125,143],[-194,56],[-47,334],[948,69],[-50,590],[1325,369]],[[16895,55723],[640,-35],[266,245],[454,165],[642,-65],[-33,-91],[535,-26],[321,-73],[111,-492],[454,-388],[-74,-102],[478,-247],[112,328],[315,243],[94,-307],[471,-89],[-66,-550],[197,-655],[267,-178],[559,-25],[85,-184]],[[3307,59743],[-14,534],[-340,-25],[-39,510],[187,49],[-7,222],[238,32],[400,360],[-212,408],[-260,75],[45,315],[197,164],[582,148],[-345,190],[-103,266],[550,32],[241,696],[90,-10],[251,595],[-259,189],[585,-139],[153,306],[-207,3],[73,229],[-34,435],[-122,21],[95,746],[164,496],[149,197],[-119,488],[-6,315],[130,307]],[[2520,59700],[787,43]],[[5370,67897],[-226,209],[-279,4],[145,194],[-506,282],[-240,-45],[-249,-182],[-330,-522],[-9,-355],[-129,-573],[1,-745],[-174,-20],[62,-180],[-130,-234],[-272,-241],[-378,-43],[-134,-219],[-350,142],[-187,-57],[-229,126],[-275,-24],[156,-163],[-258,64],[-54,-138],[-381,16],[-405,-156],[-56,-229],[128,-196],[-367,-282],[-17,-342],[-227,-373],[246,-301],[582,53],[-20,-194],[-676,-501],[424,-427],[139,-702],[126,-168],[-90,-369],[-4,-523],[215,-913],[1578,130]],[[26439,56690],[436,90],[44,-97],[726,218],[187,-427],[355,109],[14,452],[-114,155],[192,114],[46,204],[284,110],[344,-561],[1752,608]],[[8884,60573],[-134,220],[-332,94],[235,48],[181,322],[-183,153],[197,16],[31,298],[-426,99],[79,425],[271,-66],[119,343],[-709,110],[26,346],[176,-57],[144,233],[17,256],[-176,156],[222,32],[159,311],[35,346],[-239,31],[-53,162],[-486,-12],[-70,361],[640,-52],[-6,344],[350,466],[-53,490],[-177,598],[-211,279],[-544,371],[-76,364],[446,-61],[644,-292],[124,155],[-184,134],[169,138],[197,-125],[304,-52]],[[8470,59908],[316,394],[98,271]],[[7704,59887],[766,21]],[[5567,68006],[271,-8],[440,-301],[-7,-557],[193,-503],[70,-419],[433,-590],[39,-290],[-224,-602],[-291,-403],[395,-115],[-148,-369],[-75,-408],[218,-134],[-63,-265],[518,-137],[-233,-364],[-393,3],[216,-433],[117,-370],[-24,-244],[-207,-518],[-244,-449],[352,95],[287,-17],[-30,-322],[509,2],[18,-401]],[[7007,69427],[-347,-5],[-768,-234],[-99,-102],[49,-434],[98,-156],[-373,-490]],[[2520,59700],[151,-188],[-80,-1048],[284,-693],[-576,-195],[-576,49],[-217,-201],[186,-2],[8,-213],[-326,-128],[-10,-245],[270,4],[328,-163],[19,-362],[420,-432],[115,-352],[793,65],[181,-58],[63,-340],[153,-214],[382,28],[47,-246],[225,-15],[196,-583],[211,-407]],[[5695,59796],[-773,-43],[-554,20],[-1061,-30]],[[7704,59887],[-280,-38]],[[14160,60326],[-185,230],[-759,-129],[-260,-4],[-621,-329],[-324,5],[-1254,-171],[-250,23],[-1698,-11],[-339,-32]],[[23016,51148],[23,586],[144,42],[-137,746],[-130,178],[-180,-25],[-13,522]],[[19098,48399],[144,368],[302,-130],[252,-9],[57,311],[195,-143],[504,-120],[380,220],[258,-74],[133,301],[-151,82],[17,251],[-789,286],[-134,471],[209,234],[1550,350],[732,309],[259,42]],[[16817,48130],[638,73],[421,-21],[37,-164],[379,206],[-4,132],[489,226],[-18,-212],[339,29]],[[15312,48557],[188,-159],[256,107],[808,-181],[-35,-182],[288,-12]],[[13942,49863],[137,-95],[801,-300],[217,-442],[178,-38],[111,-321],[-74,-110]],[[23016,51148],[1283,-454],[487,-233],[513,174],[85,-78],[301,109],[937,-109],[131,356],[764,-195],[65,111],[1022,-214],[468,-61],[34,143],[523,-74],[-128,271],[874,-257],[1113,-137]],[[5567,68006],[-197,-109]],[[8884,60573],[529,71],[242,99],[369,431],[289,23],[208,232],[253,503],[326,119],[42,362],[370,540],[361,32],[67,284],[-542,-41],[-148,437],[323,71],[-210,276],[-3,318],[-186,342],[-306,133],[-303,337],[-645,124],[-61,311],[130,290],[229,178],[-58,498],[93,132]],[[15393,74184],[-253,-157],[359,-178],[-193,-361],[151,-199],[-95,-136],[-8,-393],[-178,-137],[165,-153],[-178,-209],[-312,160],[-114,-174],[211,-106],[-404,-510],[-493,-62],[420,-159],[-112,-177],[-597,-242],[105,-478],[-190,-104],[-412,194],[-255,-208]],[[16622,76812],[-290,-39],[-856,80],[-1031,-285],[-1692,-660],[-388,-103],[-756,-100],[-441,34],[-612,199],[-327,-270],[-747,-242],[-295,-797],[156,-39],[-21,-423],[-203,-105],[-115,-415],[-180,-339],[31,-354],[372,-320],[-239,-193],[25,-285],[301,-341]],[[84726,29813],[-7,213],[260,592],[421,-17],[681,-227],[380,59],[138,118],[265,12],[491,-151],[454,-1],[43,-89],[883,-139],[261,585],[-98,260],[50,326],[-434,307],[-324,-162],[-180,172],[156,118],[-9,238],[358,-31],[-378,530],[-499,249],[-175,173],[-88,296],[415,208],[-72,130],[355,221],[-526,525],[-300,369],[-51,239],[150,243],[100,449],[209,464]],[[77617,31644],[283,-69],[18,-394],[219,-52],[98,-171],[366,71],[128,-151],[346,119],[111,-170],[482,-308],[214,45],[177,-138],[226,81],[35,-135],[310,110],[118,211],[390,-18],[489,-573],[694,-274],[576,-64],[442,77],[379,-254],[255,-33],[261,110],[239,-69],[253,218]],[[75179,34016],[66,-92],[-184,-216],[52,-247],[318,-366],[132,85],[250,-271],[42,-204],[199,-25],[318,113],[447,-129],[163,135],[213,-190],[-35,-376],[189,-96],[268,-493]],[[73950,34977],[306,-101],[1,-108],[358,-190],[261,-351],[303,-211]],[[79490,38874],[20,-431],[-230,-105],[-142,-310],[177,46],[-109,-378],[-209,-373],[-162,-115],[109,-342],[-338,54],[-91,-200],[-199,-59],[-161,115],[-618,-358],[-9,-94],[-744,-378],[-174,-197],[111,-266],[-233,-139],[-609,-84],[-150,49],[-423,-77],[52,124],[-505,-7],[-57,-121],[-340,332],[-167,-33],[56,-248],[-151,-147],[-362,122],[118,-277]],[[87655,36092],[-384,439],[-205,-6],[-139,159],[-511,-239],[-249,14],[-337,146],[245,211],[-272,208],[-22,-121],[-265,-127],[-129,79],[-78,-283],[-213,25],[-486,-237],[-229,381],[-518,4],[-16,-260],[-280,60],[-227,279],[-523,264],[-113,-108],[-368,68],[-246,240],[-181,17],[-132,218],[-59,369],[-788,376],[-296,183],[-346,-63],[-454,392],[189,178],[-311,82],[-222,-166]],[[69921,22074],[-349,-453],[-278,37],[-92,-223],[-315,-49],[-160,-242],[-209,6],[-210,-283],[80,-201],[-399,-293],[-118,65],[-28,-381]],[[72751,25135],[-652,105],[-141,-157],[-685,-148],[-66,-168],[-304,-125],[-43,-348],[405,-203],[576,-131],[51,-93],[-334,-169],[575,-369],[-253,-18],[-426,-145],[-216,-405],[-646,-62],[-45,-189],[-433,-188],[-193,-248]],[[74806,22834],[-70,-47],[-498,279],[-316,-64],[-156,456],[-393,-83],[-20,222],[-249,-7],[-30,548],[84,215],[-78,404],[-329,378]],[[76629,19588],[168,147],[-473,108],[-116,-38],[-582,419],[-20,256],[-737,780],[25,378],[-131,88],[-91,273],[666,163],[-36,97],[-496,575]],[[75442,17358],[-185,391],[-21,248],[91,362],[593,867],[92,294],[262,103],[355,-35]],[[71681,16661],[635,142],[699,207],[440,38],[142,126],[293,31],[477,194],[831,143],[244,-184]],[[67843,20057],[348,-429],[235,2],[-67,-172],[101,-174],[-113,-106],[145,-305],[186,-77],[-139,-223],[350,-140],[512,-321],[98,-293],[-104,-206],[475,-169],[405,-513],[623,51],[231,-42],[290,162],[297,-183],[-35,-258]],[[76629,19588],[533,-99],[199,64],[304,-44],[119,-135],[503,165],[455,-155],[120,-116],[274,23],[37,403],[496,106],[-137,279],[121,326],[406,-86],[229,134],[486,29],[318,320],[141,-60],[103,187],[301,109],[480,-19],[345,-110],[103,157],[314,-34],[245,118],[104,-161],[668,181],[527,56],[321,118],[539,-105]],[[85209,22789],[-289,273],[-589,-241],[-279,75],[26,141],[-230,75],[111,115],[-487,241],[-333,275],[-14,141],[-615,393],[-532,-1],[-137,-163],[-527,-30],[-111,169],[-457,-90],[-21,-247],[-407,54],[-356,-258],[-281,-530],[-169,-61],[-345,205],[-125,302],[6,269],[-301,29],[16,406],[-167,149],[-613,43],[-410,-74],[-693,238],[3,-152],[-208,62],[-187,-130],[-146,193],[-462,-408],[-337,-194],[51,-84],[-371,-31],[158,-246],[-380,-268],[-268,-383],[73,-212]],[[85283,21239],[61,375],[-141,292],[-56,327],[133,121],[-71,435]],[[93184,41073],[-452,-240],[-149,-179],[-240,-47],[95,-127],[-219,-164],[-314,-48],[-5,-250],[-501,-384],[-104,-319],[-193,-150],[84,-189],[-832,-82],[-215,-95],[-75,-256],[-213,-351],[-336,-354],[-334,-66],[-281,87],[-162,197],[-251,-91],[-348,-430],[167,-384],[2,-422],[91,-119],[-339,-220],[197,-99],[259,-274],[-66,-322],[-200,237],[-595,160]],[[98478,28300],[416,731],[607,771],[78,279],[420,537],[-135,221],[-528,382],[-196,258],[6,270],[-391,307],[-113,393],[86,615],[203,302],[85,709],[-355,88],[-634,256],[140,288],[-57,647],[-79,251],[170,222],[-304,458],[-157,385],[-343,125],[-103,202],[-228,98],[-453,31],[-587,-98],[-175,65],[116,237],[-204,388],[-236,157],[-457,762],[-75,272],[-366,520],[-110,281],[-104,610],[-283,212],[-194,336],[-447,-4],[-307,209]],[[88117,28779],[511,195],[183,-100],[136,180],[445,14],[211,-225],[64,162],[357,194],[161,166],[-22,-383],[508,42],[267,244],[53,241],[175,96],[200,-160],[230,203],[380,-368],[161,-23],[214,313],[275,-74],[469,-294],[174,219],[103,-55],[1485,2],[475,-341],[32,122],[800,87],[519,-21],[268,-228],[1145,-536],[382,-151]],[[84726,29813],[404,-147],[36,-225],[442,-446],[1039,-92],[173,-154],[367,119],[601,16],[329,-105]],[[64886,31504],[-119,112],[-264,-135],[-543,25],[-91,101]],[[72184,25881],[-511,634],[-72,-77],[-719,252],[-94,-84],[-636,45],[-313,399],[-55,238],[-217,334],[344,224],[-415,331],[-219,-8],[-16,-177],[-493,615],[-193,42],[-12,378],[111,54],[-382,393],[-175,-94],[-161,143],[-204,-68],[-330,205],[-66,199],[-468,-279],[-283,261],[216,123],[-146,156],[-348,173],[-218,248],[57,104],[-431,192],[-14,160],[-354,373],[-266,-131],[-215,265]],[[72751,25135],[22,42],[-589,704]],[[60849,24191],[61,455],[303,63],[-10,287],[570,-306],[739,-90],[85,337],[198,190],[888,-290],[237,5],[-45,297],[768,-107],[206,145],[489,-229],[520,-182],[62,55],[349,-349],[632,-402],[550,-488],[191,-242],[532,-18],[662,-130],[182,-159],[-138,-114],[316,-212],[-84,-235],[161,-323],[331,15],[317,-90]],[[59442,25523],[-161,-303],[-235,-84],[388,-330],[285,-17],[18,-394],[387,-16],[725,-188]],[[61309,30449],[166,-159],[-145,-81],[110,-444],[-199,-59],[-104,-252],[-600,-332],[-251,40],[395,-397],[-1089,-705],[1033,-648],[722,-330],[-526,-425],[220,-280],[-195,-159],[467,-336],[-697,-495],[-50,331],[-640,48],[-484,-243]],[[63869,31607],[-457,-186],[-324,-211],[-315,-110],[-282,106],[-467,-165],[-715,-592]],[[62400,20424],[629,-252],[248,570],[755,-142],[49,126],[465,-169],[336,72],[-61,163],[378,156],[71,-106],[310,70],[181,-172],[87,155],[324,-174],[339,-18],[-160,-72],[329,-231],[274,120],[61,-115],[828,-348]],[[60771,23661],[261,-188],[-177,-91],[99,-128],[-230,-270],[-376,36],[-315,-101],[515,-374],[-78,-88],[285,-83],[267,-222],[166,95],[449,-404],[-204,-98],[88,-254],[-233,-209],[273,-43],[155,-275],[414,-262],[270,-278]],[[60849,24191],[169,-234],[-247,-296]],[[77617,31644],[-422,-223],[-61,-339],[202,-201],[-78,-517],[180,-59],[-299,-113],[22,-220],[211,-110],[-290,-207],[-140,-202],[214,-217],[-332,-524],[-370,57],[-85,-214],[-239,-33],[-430,148],[-343,-204],[-540,488],[-447,267],[-290,234],[-340,386],[-203,106],[-551,-501],[-273,-456],[-332,227],[-328,-579],[-415,-45],[-214,-160],[44,-382],[-133,-93],[503,-322],[114,-228],[556,-369],[269,-119],[160,-179],[-203,-178],[-488,-695],[-62,13]],[[85209,22789],[219,179],[41,166],[-199,581],[105,218],[-65,264],[62,179],[-87,388],[-259,406],[-150,110],[-215,467],[-247,384],[321,409],[-114,48],[157,180],[-122,77],[718,570],[-158,199],[231,431],[53,249],[542,-19],[198,65],[499,-32],[192,67],[694,-121],[179,261],[200,67],[113,197]],[[84472,17928],[-30,121],[195,179],[526,86],[52,257],[234,135],[-15,234],[-201,185],[739,164],[4,172],[373,6],[44,479],[220,90],[504,46],[534,308],[-111,399],[39,304],[-83,144],[-176,-138],[-584,-48],[6,482],[-325,81],[-162,-178],[-362,39],[-610,-236]],[[75442,17358],[582,-70],[243,-176],[269,-12],[55,-207],[199,20],[148,-177],[1122,6],[-4,309],[464,210],[693,207],[-20,-283],[152,8],[-46,-452],[308,-165],[134,-294],[318,96],[440,-161],[115,-132],[224,137],[658,178],[53,-170],[494,209],[190,159],[-38,203],[474,137],[-61,809],[735,45],[130,47],[999,89]],[[67256,35648],[-1329,943],[-268,-63],[-275,-252],[-545,-326],[-175,189],[-945,-397]],[[64842,32180],[235,124],[205,518],[213,-68],[174,115],[359,-66],[297,-417],[145,135],[419,174],[46,-156],[278,-2],[249,283],[-98,66],[333,136],[-274,211],[117,451],[-401,416],[117,1548]],[[63607,33127],[41,-209],[-93,-277],[327,-434],[356,-147],[119,168],[227,-111],[258,63]],[[63719,35742],[-149,100],[-220,-169],[91,-257],[-292,-74],[100,-136],[-40,-234],[246,-99],[698,-664],[88,-182],[-263,-54],[-99,-231],[129,-133],[-364,-203],[72,-291],[-109,12]],[[84472,17928],[639,54],[569,104],[375,124],[327,-3],[537,226],[698,75],[498,210],[60,-435],[428,82],[944,288],[506,113],[689,276],[553,122],[107,221],[643,-207],[153,201],[277,80],[188,227],[-190,64],[254,130],[28,318],[470,242],[-105,93],[29,245],[419,13],[233,398],[-285,76],[-290,321],[45,100],[388,148],[183,238],[360,143],[115,528],[-39,237],[164,360],[-220,161],[-292,37],[-304,-462],[-389,69],[109,400],[-229,415],[-402,200],[-244,312],[-459,208],[277,169],[376,18],[470,148],[348,243],[287,-61],[635,243],[-80,218],[96,211],[280,157],[169,248],[-22,217],[192,204],[296,652],[223,372],[669,279],[569,131],[424,-102],[1257,273]],[[64842,32180],[171,-387],[-127,-289]],[[75179,34016],[-447,-145],[-355,44],[-121,-163],[-250,-24],[-89,145],[-322,-61],[-224,-199],[-260,110],[-971,157],[-150,-191],[-676,326],[-332,-216],[-250,361],[-777,289],[-453,-337],[-355,280],[-308,133],[-1583,1123]],[[24660,23595],[300,49],[303,-221],[163,307],[549,370],[325,110],[202,198],[166,22],[359,245],[69,279],[205,333],[-46,368],[170,217],[379,73],[196,168]],[[28787,31675],[-698,-133],[-119,-305],[-203,-25],[-5,-168],[-248,-6],[-78,-130],[-533,-21],[-79,-359],[-698,-37],[-264,-155],[-485,-96],[-258,32],[-209,-130],[-592,-41],[-493,-159],[-248,-187]],[[29478,27867],[-184,269],[194,85],[-89,266],[-233,-1],[-246,273],[77,397],[-161,154],[-144,435],[-35,343],[-156,575],[54,360],[232,652]],[[28000,26113],[417,385],[124,359],[485,109],[555,456],[-103,445]],[[29478,27867],[142,110],[605,35],[218,199],[29,343],[458,159],[-30,66],[479,46],[631,191]],[[29816,32656],[-223,-162],[-404,-459],[-372,-251],[-30,-109]],[[32010,29016],[-560,735],[-188,335],[27,210],[-301,289],[-394,823],[-39,271],[-255,236],[-54,214],[-352,316],[-78,211]],[[29871,24813],[-529,279],[-475,387],[-263,279],[-604,355]],[[31272,20961],[-170,113],[2,248],[225,470],[-3,173],[-445,207],[-557,440],[-371,219],[360,435],[48,256],[-110,554],[-255,419],[-125,318]],[[28889,18731],[487,-66],[132,72],[-72,278],[61,179],[361,214],[-7,140],[613,239],[70,166],[328,303],[621,223],[-5,273],[-206,209]],[[31848,20964],[285,-213],[361,-493],[151,-409],[275,-125],[130,250],[738,-134],[641,-355],[649,-256],[195,115],[-95,97],[249,342],[116,-22],[230,276],[483,101],[239,310],[396,-73],[158,208]],[[35849,22811],[-72,-79],[-754,-71],[-90,-381],[-99,-103],[-296,115],[-503,-122],[-151,30],[-225,-152],[154,-181],[-321,-193],[-182,23],[-657,-303],[-848,-326],[43,-104]],[[37049,20583],[-474,384],[-247,439],[42,286],[-196,193],[-26,460],[-299,466]],[[53684,11389],[-357,-307],[-99,-227],[-331,-334],[-435,-278],[12,-230],[269,-453],[-85,-224],[-701,-232],[-15,-402],[-213,-223],[-378,-167],[-341,-32],[-723,-797],[-110,-363],[45,-430],[-276,18],[-243,-270],[-385,-830],[-97,-383],[317,-15],[309,-364],[471,-298],[26,-80],[814,278],[677,6],[256,-448],[213,258]],[[52304,4562],[-6,66],[385,345],[320,127],[319,374],[1016,1478],[861,136],[464,207],[129,195],[-97,109],[24,359],[165,126],[333,3],[341,-247],[294,-95],[502,512],[-292,402],[19,218],[-487,244],[-479,427],[156,363],[-349,-8],[-190,80],[-268,348],[-168,387],[-275,199],[-417,188],[-490,83],[-430,201]],[[32881,26504],[-223,268],[-165,432],[-122,595],[-238,331],[-123,886]],[[29871,24813],[70,104],[454,236],[95,115],[350,30],[75,255],[188,102],[203,418],[285,24],[912,331],[378,76]],[[31272,20961],[576,3]],[[35849,22811],[-278,272],[-170,423],[-348,370],[-109,320],[-408,573],[-67,7],[-500,658],[-561,463],[-173,273],[-354,334]],[[36837,27447],[367,-293],[114,-511],[530,-533],[561,-287],[18,-126],[332,-697]],[[44008,27769],[-85,178],[-261,-73],[-492,525],[71,147],[232,52],[19,197],[-311,-23],[-209,88],[-576,-302],[-31,68],[-418,-128],[60,-273],[128,-128],[-179,-168],[-226,126],[-390,66],[-270,-264],[-425,222],[-269,49],[-42,-168],[-359,-24],[13,-188],[-340,-68],[-541,141],[-766,-52],[-711,-321],[-87,199],[-337,-181],[-129,359],[-240,-378]],[[38759,25000],[456,98],[397,-99],[84,160],[522,127],[-62,132],[401,329],[-192,92],[-407,344],[-95,200],[144,375],[215,26],[479,265],[301,278],[636,66],[382,-268],[3,-95],[306,-12],[322,144],[350,265],[419,-68],[80,-84],[409,170],[157,156],[-58,168]],[[38759,25000],[419,-480],[443,-333],[390,-369],[686,-861]],[[47683,28188],[-513,-103],[-362,70],[-331,-66],[-582,204],[-590,-104],[-392,103],[-440,-282],[123,-106],[-588,-135]],[[47891,27807],[-208,381]],[[48842,26446],[-259,420],[-281,138],[186,330],[-438,453],[-159,20]],[[40697,22957],[270,243],[380,138],[264,-97],[555,-54],[379,-226],[231,-66],[465,407],[645,62],[158,115],[154,-64],[402,57],[202,166],[533,-7],[359,106],[84,257],[356,197],[45,329],[211,341],[345,394],[-20,193],[271,354],[169,-28],[497,129],[517,-12],[227,272],[18,226],[193,124],[235,-67]],[[66958,14242],[243,-88],[371,-21],[455,168],[118,105],[830,-176],[173,215],[442,190],[159,312],[204,158],[355,59],[114,638],[439,-70],[-39,177],[208,114],[29,151],[347,174],[-27,253],[302,60]],[[59760,19202],[435,-80],[-134,-406],[376,-92],[521,12],[199,-86],[86,-199],[378,-286],[556,-3],[-80,-127],[44,-486],[-84,-106],[334,-203],[25,-121],[346,-125],[-85,-169],[459,-22],[139,-133],[-26,-393],[579,164],[-50,-308],[123,46],[359,-465],[260,13],[89,-132],[563,114],[-9,-126],[364,-79],[-151,-303],[237,-514],[246,-203],[239,-2],[493,168],[247,-41],[120,-267]],[[62400,20424],[-163,-240],[-141,64],[-473,-106],[-546,-367],[-238,-62],[-296,43],[91,-202],[-366,50],[-508,-402]],[[46228,31820],[-293,-126],[-33,-394],[-126,-195],[-655,110],[-478,-13],[-248,143],[29,-192],[-405,-549],[92,-168],[-199,-143],[-213,69],[-122,-93],[-359,74],[-403,268],[-655,35],[-99,157],[-741,194],[-219,170],[-475,-39],[151,539],[-583,-208],[-226,202],[478,152],[-102,292],[-386,98],[-248,172],[-379,104],[15,195]],[[47683,28188],[-79,143],[309,455],[235,-17],[103,123],[-317,709],[-127,172],[-59,386],[-107,105],[26,320],[-279,410],[-439,86],[-29,138],[-273,189],[-419,413]],[[34395,32085],[168,-339],[104,-511],[536,-732],[50,-290],[255,-313],[-20,-337],[-206,-117],[279,-408],[151,-438],[95,-70],[719,-868],[311,-215]],[[39346,32674],[-225,165],[-278,-33],[-276,-188],[207,-242],[-245,-143],[45,-138],[-495,-43],[-449,-348],[-349,48],[-241,-67],[-339,284],[-185,56],[-272,293],[-295,89],[-321,-195],[-451,185],[-464,-248],[-318,-64]],[[54487,21268],[-152,-58],[-237,-399],[9,-308],[-261,-259],[-765,-267],[-210,-333],[-109,-365],[-370,-392],[-485,-84],[-173,-97],[-150,-258]],[[57163,19838],[-186,259],[-142,-57],[-192,343],[-414,482],[-599,340],[-254,8],[-302,-197],[-168,96],[-127,234],[-292,-78]],[[56210,16219],[109,124],[101,405],[327,330],[115,332],[282,159],[120,315],[167,151],[-138,340],[-158,193],[190,141],[0,174],[-444,427],[282,528]],[[51584,18448],[342,-63],[618,-349],[449,-115],[317,-325],[10,-119],[251,-154],[368,-55],[567,-388],[342,-148],[309,-216],[166,3],[704,-154],[183,-146]],[[40697,22957],[272,-258],[489,-617],[484,-290],[808,-404],[152,-153],[481,-156],[239,-235],[833,-94],[449,-111],[322,-457],[768,-146],[377,112],[346,15],[40,-150],[233,-7],[336,-371],[593,-104],[808,81],[176,-323],[300,-121],[467,0],[173,-142]],[[52326,23366],[-97,548],[-137,122],[-289,-119],[-355,116],[-524,289],[-41,227],[-228,5],[-23,205],[-140,29],[-440,524],[-7,209],[-226,242],[-23,231],[-472,333],[-91,-151],[-391,270]],[[49843,19026],[343,679],[143,508],[-72,162],[316,258],[42,432],[-139,178],[177,392],[409,177],[70,362],[351,266],[-107,183],[418,-54],[183,294],[261,264],[88,239]],[[57163,19838],[505,-306],[268,140],[248,-221],[492,91],[33,-313],[391,21],[472,-118],[188,70]],[[54175,21725],[101,-269],[211,-188]],[[60771,23661],[-390,245],[-200,-114],[-199,193],[-135,-210],[-408,245],[-132,-301],[-670,399],[-541,-473],[-399,-34],[-51,-317],[-248,178],[-346,-119],[-341,-302],[88,-255],[-350,-682],[-453,-194],[-704,335],[-899,-371],[-218,-159]],[[56210,16219],[457,-226],[126,-316],[290,-314],[204,-26],[428,-346],[332,-10],[153,-130],[537,-112],[187,62],[636,-189],[321,-230],[551,-202],[142,-169],[612,5],[613,210],[672,-169],[437,150],[280,-58],[224,106],[592,-54],[380,-96],[1650,136],[924,1]],[[54175,21725],[-677,438],[-329,418],[68,210],[-165,166],[-116,-80],[-511,122],[-119,367]],[[49843,19026],[1110,-430],[251,68],[380,-216]],[[42978,35552],[-360,-730],[-19,-271],[153,-26],[-98,-251],[-239,65],[-268,-446],[-425,94],[-115,226],[-282,-140],[-298,-13],[-163,-128],[102,-207],[-362,-274],[-671,-405],[35,-78],[-622,-294]],[[46228,31820],[-45,624],[-263,133],[174,179],[90,293],[-186,118],[-328,51],[-586,261],[-226,204],[-20,167],[-256,-3],[-7,189],[-195,109],[196,232],[-331,184],[155,99],[-333,83],[-269,-323],[-258,192],[-75,176],[281,133],[-172,366],[-596,265]],[[42719,36334],[-403,-168],[-582,162],[-926,10],[-334,-190],[-851,31],[-314,-266],[-3,-267],[-189,-13],[-352,136],[-429,-14],[-211,89],[-243,-58],[-479,293],[-74,-82],[-678,14],[-359,-385],[-241,-45],[-620,-360],[-257,-29],[-1039,-362],[-100,163],[-357,-166],[-96,73],[-403,-210]],[[42978,35552],[60,278],[-152,361],[-167,143]],[[33179,34690],[118,-98],[265,-495],[56,-428],[330,-813],[303,-380],[144,-391]],[[66654,42134],[-394,281],[-483,206],[-177,16],[-429,213],[-108,158],[97,264],[-268,122],[-173,367],[86,159],[-139,174],[187,122],[-345,296],[-28,309],[-176,125],[95,219],[-277,413],[-152,-153],[-345,88],[46,95],[-273,127],[51,100],[-442,209],[-261,24]],[[63409,38412],[162,-43],[307,116],[-136,210],[109,218],[-147,354],[91,146],[425,306],[-53,169],[-300,93],[287,276],[338,15],[172,-249],[592,226],[168,259],[-357,228],[229,166],[-135,111],[63,340],[581,-58],[339,703],[226,-82],[284,218]],[[59136,41775],[344,95],[150,-182],[462,-229],[778,-569],[164,131],[225,-221],[204,-346],[-235,-317],[112,-199],[398,-302],[244,-29],[177,-136],[288,146],[214,-81],[-41,-337],[248,-165],[209,-15],[220,-266],[112,-341]],[[59441,43951],[376,-251],[-737,-266],[466,-423],[-153,-85],[95,-209],[-349,78],[-276,194],[-420,-216],[258,-104],[467,-514],[-159,-48],[127,-332]],[[62746,46068],[-439,-40],[-280,177],[-323,57],[-718,-152],[-292,34],[-345,-361],[-934,-346],[281,-428],[271,-280],[-558,-477],[32,-301]],[[76419,43030],[-131,92],[-526,-26],[-235,-206],[-299,141],[-221,-122],[-126,172],[-539,-136],[204,-142],[-269,-50],[-7,-114],[-501,-225],[-157,283],[-525,-298],[-250,-77],[-433,-385],[37,-117],[-240,-169],[-481,-146],[-16,-346],[-112,-541],[-641,44],[180,-87],[-298,-611],[213,-180],[-68,-76],[830,-489],[244,-374],[19,-249],[134,-103],[-27,-421],[-193,6],[65,-522],[-272,-17],[-20,-158],[316,-460],[298,46],[159,-155],[1,-265],[133,-227],[-192,-503],[346,-352],[-103,-216],[443,-110],[-60,-153],[237,-123],[614,114]],[[79490,38874],[-201,-80],[-289,148],[-81,166],[197,230],[-301,43],[49,186],[-420,-182],[-124,207],[236,232],[-430,489],[40,276],[-308,185],[-178,482],[163,269],[-460,64],[-48,185],[-640,217],[108,182],[242,132],[-235,138],[-283,48],[132,247],[-240,292]],[[49652,47701],[398,184]],[[47839,48768],[297,-322],[221,-135],[208,101],[280,-345],[284,57],[419,-188],[104,-235]],[[53116,57636],[-352,101],[-736,-132],[-119,38],[-635,-586],[-320,-179],[-461,-60],[-248,-102],[125,-238],[-341,-152]],[[55834,54382],[-220,56],[-432,234],[178,410],[-1,216],[157,657],[-282,49],[-266,-53],[-316,44],[130,425],[365,170],[236,268],[-82,207],[-61,495],[-237,88],[-83,-163],[-283,230],[-1256,-269],[-265,190]],[[50050,47885],[-231,243],[366,141],[107,304],[-352,54],[169,166],[785,-125],[131,452],[417,211],[120,173],[-209,442],[160,356],[-213,283],[302,96],[0,172],[-172,448],[12,204],[-122,252],[288,312],[318,248],[971,626],[136,-88],[387,79],[241,-188],[84,47],[286,-372],[132,78],[362,-56],[125,116],[404,-156],[118,513],[403,-48],[130,218],[276,130],[-121,174],[72,557],[118,39],[-24,277],[-192,119]],[[63409,38412],[-550,-333],[198,-65],[-158,-157],[133,-91],[-226,-183],[473,-495],[-347,-187],[236,-455],[222,-129],[329,-575]],[[73009,45336],[-230,-305],[-45,-219],[151,-157],[-211,-394],[-139,-122],[163,-191],[235,-553],[-229,-174],[-29,-289],[102,-89],[-205,-197],[-258,-44],[65,-202],[-202,124],[-153,339],[-365,-58],[-91,-193],[-555,78],[25,187],[-442,162],[-294,-316],[-164,-32],[-464,-372],[-386,-244],[-496,-64],[-430,41],[-305,-484],[-608,112],[-255,233],[-380,78],[-160,143]],[[76875,44583],[-99,186],[-201,56],[-211,-131],[-291,-40],[-209,94],[-30,314],[-194,115],[-19,391],[-436,-87],[-300,249],[-78,-131],[24,-333],[-392,-76],[-173,256],[-393,-297],[-83,-186],[-200,52],[-89,265],[-374,106],[-118,-50]],[[76419,43030],[560,178],[-90,456],[63,141],[-161,285],[-280,224],[364,269]],[[62976,47509],[-216,-105],[102,-157],[-253,-236],[234,-719],[-97,-224]],[[70862,49932],[-542,-475],[-430,13],[-662,-168],[-272,-213],[-472,-31],[46,-164],[-263,-55],[-133,-275],[-579,-190],[-13,-309],[-530,-574],[-296,80],[-186,-254],[-544,-225],[-410,-18],[-71,382],[-317,-9],[-391,77],[-41,-125],[-324,-116],[-355,322],[306,549],[-732,-120],[-56,-533],[-619,8]],[[73009,45336],[-180,122],[172,284],[-223,399],[281,239],[-444,246],[-271,-142],[-365,239],[-8,155],[-346,379],[-322,142],[117,87],[-167,387],[124,97],[-87,322],[-188,-32],[-139,152],[175,129],[-230,228],[158,153],[-79,197],[124,174],[-221,378],[90,184],[-118,77]],[[70707,51026],[-626,277],[-252,565],[-359,18],[33,197],[-381,679],[-208,-80],[-313,56],[-217,-104],[-477,246],[-207,-46],[-67,265],[209,126],[84,567],[187,152],[70,267],[213,12],[221,330],[-341,321],[-522,203],[-254,36],[-135,-149],[-104,141],[-954,252],[-415,190]],[[70862,49932],[-37,206],[260,390],[-67,145],[-335,184],[24,169]],[[65892,55547],[-78,-222],[159,-252],[83,-334],[-47,-570],[-82,-227],[-376,-250],[-216,-1],[-314,-225],[-248,-330],[-650,52],[-266,123],[-413,27],[-485,-158],[-773,-135],[-70,-73],[407,-44],[-579,-236],[-197,-209],[290,-216],[6,-158],[266,-649],[-251,-663],[-408,-615],[323,-227],[41,-156],[-136,-233],[15,-234],[178,-203],[384,-82],[-13,-370],[330,-250],[-38,-341],[-223,-44],[160,-204],[395,78],[33,-271],[-123,-136]],[[76904,51371],[-355,-55],[41,-219],[-206,-191],[-59,126],[-395,-52],[-225,-167],[65,-165],[-141,-160],[382,-178],[-519,-476],[-386,-248],[-25,-222],[375,-30],[87,-104],[394,-21],[-124,-284],[-543,-168],[19,-192],[-248,-50],[-151,-345],[427,-468],[409,97],[99,-355],[-174,-41],[251,-228],[527,153],[281,-115],[-70,-296],[262,-67],[78,189],[357,71],[245,-85],[-11,119],[349,-186],[257,-16],[60,-417],[-110,-211],[140,-144],[354,391],[351,77],[62,-477],[135,-278],[-26,-148],[-238,-236],[40,-86],[-232,-330]],[[86726,45936],[-166,-130],[-522,83],[-431,-114],[-212,223],[-313,31],[-107,161],[-208,28],[-334,269],[-77,-111],[-462,434],[-1,285],[-169,111],[-209,305],[-325,22],[-525,-423],[-585,82],[-319,-34],[-145,78],[-243,-105],[-293,97],[-239,-162],[-587,65],[-97,-96],[-307,42],[-203,281],[-214,131],[-695,292],[-171,177],[615,133],[-244,395],[276,-103],[645,-20],[650,58],[156,362],[665,84],[45,219],[-272,-73],[-192,92],[179,240],[-103,195],[-177,-72],[-463,100],[-1041,-157],[-231,89],[-319,-98],[-281,26],[97,135],[-114,362],[20,245],[218,88],[-275,193],[-293,6],[-41,160],[-237,53],[109,-217],[-181,-128],[-242,97],[-140,-225],[-487,883],[-5,291]],[[87142,45755],[-416,181]],[[78713,45083],[836,-1157],[373,3],[321,158],[236,-52],[-52,-161],[163,-147],[438,144],[413,258],[518,66],[164,-203],[132,162],[371,-14],[267,-126],[623,86],[216,-48],[148,122],[68,451],[-97,198],[263,120],[-52,287],[290,485],[59,-342],[106,-53],[423,406],[608,-94],[-136,-197],[576,-287],[185,287],[378,-244],[330,209],[261,355]],[[75057,52841],[-180,-108],[-261,-330],[355,-148],[42,-211],[-495,-122],[-210,-282],[-358,-284],[-84,428],[-753,-68],[-458,90],[-186,286],[-195,140],[15,200],[-277,46],[-146,-400],[-441,-258],[-89,132],[-596,50],[73,-262],[211,-71],[21,-254],[-107,-162],[141,-137],[-147,-134],[-225,44]],[[76904,51371],[195,554],[-5,274],[-170,448],[-185,202],[-303,82],[-1092,-18],[-287,-72]],[[76875,44583],[334,-23],[367,74],[366,-15],[283,151],[266,-95],[74,137],[203,-140],[-55,411]],[[41571,38676],[148,332],[-81,261],[171,435],[-222,224],[-216,554],[126,168],[325,137],[72,253],[272,-27],[509,164],[171,170],[498,254],[196,215],[287,-249],[368,-107],[857,18],[382,-49]],[[38190,45966],[-171,19],[-351,-733],[389,-122],[-217,-445],[390,-121],[-154,-384],[-271,120],[-184,-186],[-299,158],[-502,-231],[246,-211],[-365,-319],[-471,-187],[-216,-555],[211,-131],[138,387],[266,-39],[113,-208],[-102,-211],[771,-281],[278,-213],[-124,-198],[-306,106],[-106,-179],[328,-137],[-104,-116],[917,-728],[-73,-127],[141,-225],[-85,-135],[176,-264],[453,-247],[161,-265],[221,-81],[459,-476],[297,-183],[634,-147],[259,222],[291,-56],[149,134],[194,-295]],[[47051,44119],[-248,10],[47,432],[-363,25],[-152,124],[-368,-249],[-1909,1803],[-204,-78],[-444,464],[-184,-141]],[[46785,43699],[266,420]],[[45434,41429],[49,215],[259,366],[187,-104],[399,567],[-358,195],[234,414],[271,76],[146,387],[164,154]],[[54408,30222],[43,-278],[-99,-105],[-406,101],[-184,-152],[-285,80],[-286,-18],[-25,-142],[-391,-236],[-44,-105],[-327,-101],[-262,-301],[-239,-133],[-100,231],[-162,-44],[-321,306],[-264,-323],[-101,220],[-539,-257],[-348,-494],[-277,-131],[-245,-18],[-334,-204],[-988,-112],[-333,-199]],[[59442,25523],[-250,54],[-197,237],[-552,385],[-25,142],[-243,55],[-97,206],[-219,-164],[-429,166],[-89,246],[-501,-202],[-429,2],[-303,150],[-102,235],[-196,-31],[-76,305],[-199,-38],[-187,266],[-283,104],[-77,134],[336,248],[-477,316],[247,146],[483,-67],[266,379],[-418,267],[-268,74],[598,580],[-581,435],[-272,-260],[-494,329]],[[47583,39860],[-1772,1381],[-377,188]],[[47844,37082],[-517,529],[-196,338],[-40,546],[96,239],[-134,108],[121,170],[225,-33],[-218,538],[402,343]],[[42236,37429],[190,198],[467,-199],[201,351],[418,-427],[11,-133],[446,-336],[309,193],[286,-186],[278,366],[112,12],[300,-269],[78,251],[341,125],[93,-363],[330,50],[97,-87],[241,79],[-26,143],[349,194],[435,-425],[321,180],[167,-185],[164,121]],[[41571,38676],[-124,-276],[-294,-147],[118,-345],[-131,-20],[-15,-210],[550,-22],[293,-66],[268,-161]],[[49109,39693],[486,-308],[488,-582],[533,-401],[136,-211],[776,-173],[262,-351],[421,-313],[109,-398],[596,-725]],[[49523,41127],[-377,-330],[254,-42],[451,-214],[-323,-385],[132,-70],[-121,-170],[-430,-223]],[[51031,40205],[-603,396],[-905,526]],[[52916,36231],[764,234],[11,174],[336,318],[-346,335],[88,38],[-303,403],[-139,-57],[-235,235],[285,338],[40,251],[-264,120],[-585,74],[-462,282],[-254,4],[-209,159],[397,394],[-1009,672]],[[42236,37429],[-30,-528],[339,-310],[306,-172],[-132,-85]],[[54357,30393],[-150,-109],[-680,67],[-276,177],[58,224],[-202,250],[-34,477],[-275,454],[25,89],[-284,133],[-156,493],[-395,533],[-15,167],[-218,237],[-418,251],[-127,416],[-377,484],[-435,228],[-575,97],[-311,237],[-432,617],[-132,418],[-522,125],[-582,624]],[[54408,30222],[-51,171]],[[54800,31209],[5,-138],[-405,-295],[133,-233],[-176,-150]],[[61309,30449],[-1033,1038],[-1102,-332],[-9,-221],[-307,111],[-336,-114],[-482,65],[-340,-217],[81,-194],[-585,-223],[-123,131],[-653,-359],[-368,414],[-366,286],[-273,56],[-613,319]],[[63607,33127],[-239,102],[-283,-329],[14,-192],[408,-366],[-83,-75],[384,-387],[61,-273]],[[49523,41127],[-810,468],[93,304],[-182,196],[-382,109],[-111,129],[42,665],[114,138],[-86,337],[-512,124],[-194,-325],[-202,186],[-404,-9],[162,343],[-266,-93]],[[47583,39860],[168,-38],[732,225],[244,-64],[382,-290]],[[52916,36231],[126,-181],[-130,-123],[236,-461],[-65,-269],[6,-423],[179,-590],[112,-201],[659,-597],[356,-41],[796,-443],[528,-169],[200,-189],[79,-265],[-40,-459],[-198,-381],[-306,-255],[-611,137],[-43,-112]],[[59136,41775],[-231,11],[-1,-164],[-471,-620],[-471,-12],[-149,-234],[-198,67],[-175,-240],[-678,316],[-491,428],[-529,359],[-87,-30],[-353,272],[-304,103],[-393,-148],[-169,86],[-492,-366],[-553,25],[-276,145],[-322,-140],[-310,-304],[-811,-527],[-389,-118],[-213,-272],[-39,-207]],[[49652,47701],[12,-222],[155,-59],[-236,-373],[281,-510],[-466,-216],[64,-355],[-342,29],[149,-208],[-133,-101],[-278,27],[-210,-108],[220,-146],[-840,-691],[-407,-253],[-372,28],[-198,-424]],[[59441,43951],[-780,268],[-400,-38],[-335,119],[-285,242],[-152,-68],[-454,89],[83,-604],[-522,-36],[-414,215],[281,265],[-227,249],[-551,140],[-488,203],[-200,234],[-491,359],[-165,-210],[-442,667],[-113,107],[-622,296],[-511,-138],[-141,139],[-199,432],[-314,262],[-146,-132],[-135,144],[52,169],[-522,47],[-227,-483],[-324,100],[54,253],[-563,630],[-138,14]],[[71260,77250],[-447,108],[97,517],[-533,129],[73,415],[140,419],[-805,177],[207,443],[483,-127],[75,188],[-6111,1595],[-887,126]],[[69944,75942],[234,244],[128,-72],[344,452],[90,-36],[214,244],[122,377],[184,99]],[[66946,76333],[761,-120],[69,236],[265,-23],[654,-320],[421,-136],[103,-110],[182,97],[543,-15]],[[64701,76422],[523,-130],[290,31],[703,-127],[136,368],[612,-71],[-19,-160]],[[53116,57636],[208,28],[319,336],[579,-13],[27,152],[-316,180],[-95,249],[-305,24],[86,308],[-230,275],[-417,94],[-226,380],[-322,275],[-200,15],[-305,237],[-112,218],[-184,82],[-284,433],[-77,334],[-394,-188],[-708,-696],[-294,-8],[-105,170],[-316,54],[-277,-62],[-235,595],[-318,284],[105,55],[-302,228],[-402,58],[-105,106]],[[61510,72801],[72,108],[-167,128],[193,216],[-189,24],[-142,259],[-329,-205],[-34,195],[-157,79],[188,221],[-217,-9],[-104,456],[43,104],[549,426],[257,34],[42,140],[-391,372],[-207,-49],[-143,219],[272,52],[21,322],[-83,233],[63,250],[-50,295],[-495,374]],[[58636,72724],[892,-62],[538,-198],[21,-301],[130,-61],[220,127],[182,-52],[536,293],[355,331]],[[53573,75445],[235,-182],[593,212],[603,93],[42,-616],[390,3],[55,-135],[331,90],[188,-214],[313,191],[217,-502],[199,-143],[167,226],[297,-361],[189,-368],[-240,-152],[250,-206],[45,-163],[494,-64],[231,50],[426,323],[-34,-324],[72,-479]],[[59266,77940],[-627,-640],[-208,183],[-181,-54],[-681,160],[-260,152],[-773,626],[-118,-160],[-274,-60],[-376,561],[-321,35],[-155,217],[-89,-139],[121,-503],[-69,-622],[-238,-18],[-225,97],[-71,-269],[113,19],[-133,-292],[-409,-29],[-334,-430],[198,-159],[-226,43],[-154,-112],[-73,-240]],[[44658,67580],[-137,199],[-172,7],[-179,295],[-365,226],[48,253],[-99,113]],[[41080,67586],[2994,-263],[389,100],[195,157]],[[65936,72158],[503,168],[394,-129],[111,-134],[288,104],[-209,382],[378,94],[-251,781],[-499,-112],[-134,106],[123,173],[314,68],[183,-50],[304,93],[-271,462],[-228,239],[-105,248],[62,228],[-104,309],[-480,-10],[-139,475],[194,-35],[85,398],[400,-94],[160,282],[-69,129]],[[62649,72837],[258,-66],[233,-181],[449,153],[405,-109],[236,-234],[262,252],[317,-9],[42,-107],[270,11],[-17,-144],[534,-201],[96,-123],[202,79]],[[61510,72801],[283,-58],[337,128],[-125,106],[319,-14],[325,-126]],[[74441,73950],[-331,538],[282,63],[-41,243],[418,47],[935,-91],[341,120],[59,279],[160,125],[689,149],[805,31],[-45,521],[-1043,-91],[82,534],[-432,49],[-65,-92],[-389,-99],[-13,572],[-230,20],[148,489],[-1206,395],[-181,-432],[-986,245],[-211,105],[-69,-273],[-251,145],[-119,-193],[-377,97],[-103,-330],[-446,-3],[-562,137]],[[71853,73737],[253,-94],[128,355],[698,65],[617,-139],[892,26]],[[69944,75942],[468,-415],[138,-394],[447,-356],[152,-314],[393,-153],[147,-237],[-23,-285],[187,-51]],[[74353,66073],[-294,123],[-11,271],[153,128],[101,411],[-66,184],[336,82],[-247,213],[-397,-95],[-179,210],[-281,-283],[-161,173],[-221,-78],[74,-123],[-516,-229],[-739,-264],[129,-203],[-1202,-231],[-197,-106],[-334,173],[105,145],[-1014,-193]],[[72962,61888],[59,655],[60,130],[584,160],[202,192],[32,166],[197,34],[148,251],[-93,149],[-532,166],[168,191],[864,325],[196,178],[37,483],[-391,-118],[-286,459],[238,68],[-72,141],[124,198],[-9,213],[-135,144]],[[71172,61174],[807,149],[-41,139],[532,316],[113,-212],[379,322]],[[69392,66381],[410,-420],[-354,-212],[-553,-156],[-196,207],[-189,-133],[111,-174],[-663,22],[-759,-399],[-102,-273],[-247,-21],[-266,-450],[517,-117],[-141,-152],[386,-256],[-417,-232],[339,-371],[104,81],[452,-79],[134,-161],[326,-81],[137,-140],[112,98],[23,-286],[193,-195],[505,53],[604,-122],[848,100],[167,-17],[3,-209],[394,1],[-4,-346],[225,54],[29,-527],[-399,-91],[51,-203]],[[77662,66184],[254,-177],[524,-104],[798,-396],[475,322],[194,206],[485,-61],[158,-160],[118,-309],[409,-106],[458,596],[368,-8],[204,-577],[218,-200],[89,-266],[-228,-155],[8,-430],[678,54],[830,-47],[-131,269],[993,130],[-21,-93],[401,14]],[[81510,69617],[-248,-259],[-176,-443],[-309,-260],[-183,-64],[-397,441],[-375,102],[-522,-66],[26,-142],[-415,-64],[-441,28],[-338,-64],[-709,-30],[41,-186],[-182,-35],[46,-302],[156,-40],[60,-299],[-284,-291],[324,-250],[502,-102],[232,-231],[-253,-122],[-133,-282],[37,-230],[-307,-242]],[[84944,64686],[29,162],[283,255],[-133,136],[184,396],[-39,523],[47,124],[-205,349],[20,782],[75,72],[-290,288],[191,205],[264,695],[-253,293],[-750,209],[-339,-5],[-301,122],[-70,172],[-201,-104],[-458,287],[-556,-349],[85,-105],[-1017,424]],[[53668,69901],[443,34]],[[51964,73525],[-34,-252],[385,-143],[326,-302],[-29,-212],[173,-234],[-99,-149],[-261,-54],[214,-610],[61,-40],[593,196],[299,-783],[100,-569],[-24,-472]],[[54111,69935],[289,42],[14,770],[734,148],[108,111],[347,-5],[16,172],[715,48],[523,160],[174,337],[195,-38],[616,372],[466,170],[-97,315],[29,201],[164,-116],[232,102]],[[47921,66703],[816,-69],[263,20],[700,333],[449,69],[-28,117],[317,-137],[312,468],[-12,120],[244,448],[318,21],[-36,310],[216,111],[615,610],[-74,169],[175,43],[-152,278],[754,139],[251,-26],[-30,198],[649,-24]],[[44658,67580],[211,136],[404,-105],[1691,-675],[599,-181],[358,-52]],[[47544,63182],[254,226],[-213,364],[192,115],[-241,394],[79,192],[-71,195],[173,12],[-407,417],[-72,259],[91,66],[302,1091],[272,-28],[18,218]],[[67491,70334],[1136,300],[89,228],[356,345],[421,486],[345,271],[168,-176],[562,212],[541,67],[-527,414],[95,174],[412,297],[290,361],[387,246],[87,178]],[[65936,72158],[269,-501],[-180,-83],[502,-916],[290,231],[117,-111],[365,-14],[-189,-107],[172,-330],[209,7]],[[79783,56443],[15,340],[-235,4],[-463,167],[122,233],[-87,59],[25,342],[-315,444],[-246,-12],[-80,223],[-946,315],[-181,-166],[-372,-128],[-165,459],[-161,206],[78,306],[-227,59],[-113,152],[333,235],[-378,302],[-156,-1],[-392,250],[-564,168],[-137,245],[-421,-196],[-362,278],[-258,394],[-309,196],[-173,302],[-653,269]],[[77622,55851],[223,-144],[772,-261],[197,174],[42,378],[276,323],[651,122]],[[69327,57958],[173,-129],[332,-48],[-175,-282],[154,-91],[305,100],[41,-170],[488,0],[387,-129],[212,90],[447,-45],[449,101],[555,-101],[174,-113],[310,98],[980,-553],[361,37],[177,-160],[827,249],[277,-117],[141,-354],[595,-4],[150,-79],[219,86],[678,-376],[38,-117]],[[71172,61174],[67,-261],[175,-109],[-434,-52],[-245,-141],[214,-250],[287,-19],[46,-289],[-84,-82],[327,-526],[-364,-28],[-821,-164],[-236,-111],[-541,-435],[-112,-177],[-124,-572]],[[54111,69935],[224,-401],[-371,-199],[128,-129],[-126,-110],[220,-470],[-415,-141],[50,-366],[136,-3],[91,-215],[354,-114],[501,457],[225,44],[562,-130],[65,125],[852,-233],[586,45],[314,-40],[400,-174],[325,18],[675,-270],[-20,229],[425,175],[576,-8],[-62,577],[-109,20],[-33,270],[192,39],[-53,443],[422,-77],[251,161],[221,359],[300,-13],[277,531],[24,307],[396,81],[-35,176],[310,38],[-173,264],[349,13],[90,500],[-180,72],[56,202],[274,232],[60,192],[-70,307],[173,-56],[81,174]],[[77622,55851],[-251,-65],[-65,-297],[-148,90],[-414,-536],[87,-288],[-178,-248],[-526,-194],[-276,19],[62,-158],[-386,-158],[-183,-284],[-13,-237],[-408,-218],[134,-436]],[[84931,57374],[-564,-166],[-20,-270],[366,-166],[51,-128],[-202,-193],[-290,-91],[-400,-269],[-325,47],[-324,-150],[80,-271],[-68,-509],[237,-204],[-38,-233],[-256,-277],[-105,-394],[-256,150],[58,101],[-265,187],[-36,322],[-166,301],[-40,371],[-464,-254],[-372,86],[-512,-123],[-238,-238],[-193,-72],[-587,10],[-369,-184],[-264,595],[-83,378],[167,209],[-11,193],[284,-82],[57,393]],[[86726,45936],[136,95],[13,367],[308,408],[452,408],[18,245],[180,278],[296,180],[-20,720],[178,261],[-448,1022],[131,377],[421,274],[-23,134],[-958,335],[-153,127],[8,195],[515,463],[191,1],[222,-412],[529,314],[173,-140],[266,117],[368,3],[603,-267],[422,4],[99,109],[262,-48],[141,285],[208,174],[-147,127],[82,118],[-283,-50],[-624,12],[-252,-116],[-590,3],[-455,252],[-673,78],[-540,-33],[-696,399],[31,144],[-235,237],[-7,134],[-430,405],[-31,120],[261,158],[251,270],[463,209],[-358,586],[-179,67],[-348,404],[-511,207],[-401,611],[50,73],[-393,197],[79,265],[-123,379],[-274,153]],[[69392,66381],[-896,-172],[-309,-117],[-492,80],[-217,410],[-218,9],[-114,240],[-260,-108],[-442,28],[-566,-53],[-80,712],[-322,-98],[-139,-161],[-268,118],[173,244],[-587,274],[114,561],[3,321],[227,74],[245,668],[240,-201],[105,175],[355,31],[314,278],[1127,534],[106,106]],[[63993,56559],[28,85],[1630,-399],[-8,161],[442,-12],[479,289],[410,120],[442,286],[596,63],[425,258],[355,116],[535,432]],[[55834,54382],[151,380],[700,-389],[146,295],[-215,327],[344,140],[294,497],[-210,641],[56,250],[630,-168],[542,161],[585,114],[23,-335],[109,-218],[196,-111],[263,-6],[281,201],[-35,557],[119,225],[181,53],[892,-12],[346,-222],[498,-150],[332,144],[427,1039],[103,156],[324,63],[143,-74],[382,-456],[44,-163],[-85,-401],[116,-123],[477,-238]],[[63993,56559],[827,-408],[1072,-604]],[[15927,32404],[-199,253],[-129,563],[-494,308],[221,291],[-389,58],[-790,253],[-243,350],[-215,73],[-115,-222],[113,-262],[-176,-40],[-231,209],[-42,246],[-461,-25],[-256,128],[-258,-305],[-127,60],[-606,-126],[-427,-247],[-99,-153],[-420,71],[-24,90],[-604,-361],[-218,-54],[167,-537],[-145,-253]],[[9760,32772],[-78,-264],[143,-356],[-432,-585],[-83,-372],[-128,-30],[-21,-269],[125,-135],[325,-23],[170,-333],[435,54],[295,134],[639,189],[415,41],[293,144],[290,-152],[65,84],[498,-304],[305,270],[393,61],[218,113],[237,-40],[225,339],[131,-51],[297,166],[570,133],[173,588],[312,-66],[179,282]],[[8377,38281],[-292,-131],[-218,-351],[186,-222],[180,-571],[-56,-346],[115,-473],[287,-66],[-173,-334],[-369,-419],[-24,-422],[-265,-427],[171,-259],[282,-212],[-54,-182],[162,-275],[516,-248],[237,-371],[272,-32],[168,-224],[258,56]],[[12741,38792],[-411,-222],[-426,-111],[-409,-182],[-402,329],[-257,-57],[-298,-202],[-101,141],[-629,-191],[-233,49],[-640,-287],[-558,222]],[[18978,35969],[-146,138],[-564,122],[-124,-230],[-400,136],[-55,375],[-328,291],[41,284],[-323,226],[-183,267],[-404,-15],[-229,-370],[-348,-62],[226,146],[-507,0],[-36,283],[126,205],[-459,33],[-164,205],[-419,-72],[-241,263],[-375,11],[-315,241],[-616,-187],[-326,149],[-68,384]],[[6990,39789],[103,338],[788,176],[317,-127],[38,645],[9,1004],[298,234],[-221,310],[-45,223],[266,235],[116,364],[-278,223],[59,92],[-286,115],[360,200],[358,-169],[397,-66],[189,-180],[1308,478],[389,-63]],[[4944,49715],[54,-224],[631,-734],[66,-255],[-124,-313],[-608,-644],[-598,306],[-318,-332],[578,-328],[-611,-660],[-53,-258],[137,-281],[430,-348],[-301,-271],[-106,-238],[-432,-211],[-494,443],[-880,-192],[-239,-97],[-254,-485],[-260,330],[-528,-42],[130,-244],[496,-403],[390,86],[827,-35],[351,185],[345,11],[227,-76],[101,-251],[340,-309],[-21,-225],[607,-30],[264,80],[284,-182],[337,227],[187,-179],[131,21],[143,-272],[248,59],[20,-222],[-106,-204],[-264,-100],[134,-160],[10,-1289],[97,-294],[-73,-96],[257,-395],[-21,-378],[317,-354],[198,-63]],[[7274,48565],[-191,241],[-876,499],[-503,159],[-456,210],[-304,41]],[[8501,46494],[-1227,2071]],[[8415,45831],[139,406],[-53,257]],[[12339,44976],[-1831,-102],[-266,-131],[-496,2],[-327,-151],[-338,13],[-425,98],[-248,138],[-242,274],[-38,176],[98,285],[189,253]],[[11155,43821],[126,168],[385,6],[2,147],[446,95],[-195,189],[31,213],[389,337]],[[9504,50075],[-379,30],[-125,-137],[-450,39],[-194,82],[-183,-529],[-595,156],[-33,-230],[150,-33],[-241,-561],[215,-134],[-160,-231],[-235,38]],[[8501,46494],[946,-67],[291,219],[-6,168],[-408,256],[-228,21],[-11,360],[306,80],[448,431],[128,-33],[108,467],[362,363],[-67,86],[184,172],[-489,140],[-278,167],[-312,-1],[31,292],[185,90],[-246,193],[59,177]],[[15142,46236],[644,-519],[509,-199],[624,-118],[778,-225]],[[16817,48130],[-29,-352],[-193,-101],[-134,-370],[-414,106],[-135,-491],[-155,-89],[-17,-556],[-439,140],[-159,-181]],[[17697,45175],[454,16],[868,158],[330,7],[2,226],[-182,206],[28,551],[-296,103],[60,199],[221,222],[-397,86],[-185,-69],[-137,-279],[-266,64],[-105,291],[-256,-50],[-122,203],[320,422],[-151,169],[74,194],[310,23],[883,405],[-52,77]],[[9504,50075],[86,429],[136,-106],[132,215],[-214,125],[104,192]],[[4340,51010],[-164,-377],[-291,73],[-29,-104],[-597,195],[-380,-300],[70,-295],[147,-143],[339,-123],[320,-28],[497,-174],[692,-19]],[[15142,46236],[-307,-147],[-791,-33],[-245,154],[-377,-374],[-585,-352],[-498,-508]],[[14646,40888],[591,75],[261,-59],[522,127],[2,281],[259,-30],[-132,269],[279,274],[237,355],[23,184],[430,472],[216,151],[328,-125],[22,404],[-416,376],[588,-35],[536,-130],[-77,168],[248,55],[72,175],[-1326,415],[79,174],[305,-89],[72,159],[-305,88],[237,553]],[[11155,43821],[-73,-322],[209,-475],[458,177],[140,-360],[350,122],[423,-743],[635,-477],[795,-695],[385,-61],[169,-99]],[[14646,40888],[-263,-225],[-14,-414],[-364,-111],[-70,-130],[156,-219],[-597,-114],[-68,-170],[-525,-51],[145,-200],[-60,-215],[-245,-247]],[[20907,35797],[46,81],[-365,291],[-65,377],[-476,565],[-464,187],[-285,-95],[-671,87],[-354,158],[-171,508],[-497,249],[-343,283],[-17,207],[161,157],[654,409],[161,233],[-35,253],[-413,-75],[-347,157],[-410,295],[-469,270],[-750,104],[-644,6],[-507,384]],[[15312,48557],[-271,10],[-341,-163],[-184,-408],[-472,-558],[-93,-199],[-498,121],[-386,-240],[-392,-23],[-208,-350],[-272,-92],[-54,-157],[-497,9],[-256,-69],[-258,-535],[-336,-397],[-225,35],[-815,521],[-524,-214],[-137,-229],[-678,212]],[[13015,45980],[-43,95],[294,180],[84,-92],[-335,-183]],[[6990,39789],[188,-107],[-116,-176],[62,-514],[239,26],[176,-119],[644,49],[129,-85],[-116,-183],[181,-399]],[[29816,32656],[3363,2034]],[[61484,86533],[214,-292],[466,-222],[406,-347],[316,334],[604,-48],[716,-277],[460,-266],[453,-119],[7,111],[325,-26],[285,-373],[498,-21],[762,-350],[565,-319],[320,77],[77,-182],[-241,-304],[-78,-501],[105,-132],[769,-163],[480,23],[350,-65],[604,-200],[-167,344],[203,309],[-5,415],[142,227],[-105,87],[126,179],[-17,410],[144,395],[266,90],[257,-24],[45,199],[304,19],[110,225],[288,32],[-160,202],[104,109],[-209,142],[222,110],[-23,204],[225,87],[-212,85],[121,151],[-324,51],[88,329],[160,-51],[-63,276],[22,345],[360,76],[56,168],[284,-82],[32,277],[379,-76],[-11,231],[423,489],[270,149],[-149,97],[142,170],[103,375],[206,109],[161,545],[-157,307],[10,190],[-172,156],[39,497],[-259,159],[-576,199],[-404,14],[-263,94],[-143,-89],[-936,461],[-802,103],[44,466],[-143,39],[93,679],[-16,344],[-240,41],[107,610],[167,158],[-335,97],[-546,-74],[-465,2],[-588,-61],[-703,118],[-290,-869],[6,-492],[-107,-79],[34,-465],[-95,-26],[-455,-488],[-218,-147],[-394,-137],[-362,-412],[-256,-20],[-314,216],[-629,34],[-297,-202],[-292,-58],[-402,-512],[-374,-111],[-306,-447],[-345,-22],[-70,-200],[-484,63],[-5,-215],[-377,35],[-232,-128],[-147,-403]],[[41764,7354],[138,-369],[364,-566],[-139,-314],[278,-264],[298,-153],[-55,-394],[865,-1182],[58,-226],[284,-155],[17,-178],[-390,-385],[-231,-417],[-14,-189],[141,-162],[628,-121],[424,23],[411,-99],[769,12],[168,-128],[-22,-273],[332,-96],[602,159],[756,121],[323,136],[518,-209],[413,129],[414,-40],[-45,-142],[121,-252],[-14,-522],[-87,-276],[139,-557],[556,-183],[555,-82],[331,51],[751,-40],[214,239],[627,247],[783,138],[283,-15],[817,165],[-35,620],[-120,429],[-185,146],[-696,311],[-526,450],[9,216],[-257,523],[-127,364],[142,323],[-46,395]],[[43555,17104],[42,-284],[338,-344],[-24,-358],[296,-324],[250,-136],[23,-265],[-293,-135],[-237,-266],[-44,-397],[-409,-179],[-88,-169],[-380,-28],[12,-237],[-162,-162],[237,-681],[-203,-442],[-678,-544],[-260,-401],[428,-351],[229,-433],[809,-503],[-67,-96],[277,-207],[272,-503],[-430,-289],[182,-134],[-68,-398],[-746,-56],[5,-114],[-324,-27],[106,-436],[-139,-225],[-745,-626]],[[53684,11389],[-565,304],[-292,449],[-328,-74],[-689,374],[-342,306],[-82,288],[-351,383],[-799,365],[-195,162],[-957,571],[-249,254],[-37,365],[-461,488],[10,229],[-270,44],[-416,175],[-253,339],[57,173],[-107,179],[-844,332],[-561,151],[-457,-42],[-261,-307],[-483,-133],[-450,166],[-295,42],[-18,107],[-434,25]],[[77662,66184],[-341,-37],[-319,-201],[-143,138],[-433,202],[-145,217],[-508,-211],[-447,90],[-973,-309]],[[84931,57374],[-324,107],[277,187],[-288,115],[-166,355],[-42,277],[-925,60],[-189,88],[-47,187],[196,230],[-12,256],[-565,192],[127,27],[443,355],[-38,404],[164,326],[-47,190],[524,121],[1422,544],[-156,520],[-314,123],[-317,-36],[90,1095],[-42,587],[-123,19],[1,571],[144,18],[220,394]],[[43555,17104],[-850,226],[-328,173],[-258,273],[-260,85],[-491,34],[-450,165],[-508,285],[-1049,362],[-173,210],[-150,-39],[-893,349],[-334,253],[-292,641],[-189,92],[-281,370]],[[35659,10895],[376,-209],[474,86],[152,-175],[-374,-435],[196,-663],[194,-123],[273,49],[369,323],[229,10],[392,-170],[442,103],[313,-357],[217,-153],[23,-194],[-150,-270],[126,-204],[-154,-83],[25,-194],[338,-495],[230,1],[477,271],[319,365],[148,62],[456,-145],[309,-325],[343,-149],[73,-242],[289,-225]],[[93184,41073],[-409,437],[-155,286],[229,429],[298,334],[-68,405],[-267,249],[-530,242],[-309,273],[-713,240],[-285,300],[-379,225],[-65,282],[-236,198],[-835,468],[-1146,155],[-3,125],[-363,48],[-636,-81],[-170,67]],[[81510,69617],[-827,176],[-544,15],[-1518,-39],[14,195],[-804,-79],[-506,23],[-1059,244],[30,474],[-94,127],[8,285],[-213,-34],[85,397],[-281,5],[58,152],[-226,197],[-150,300],[-289,3],[-127,286],[61,110],[-213,183],[80,114],[-164,139],[74,258],[-275,198],[-202,348],[145,72],[-132,184]]],"transform":{"scale":[0.0038479278343284203,-0.004800048000480004],"translate":[287.60553224749617,490]}} \ No newline at end of file diff --git a/src/onegov/election_day/static/municipalities/2025/fr.json b/src/onegov/election_day/static/municipalities/2025/fr.json index f30827bfd1..1ae77481fd 100644 --- a/src/onegov/election_day/static/municipalities/2025/fr.json +++ b/src/onegov/election_day/static/municipalities/2025/fr.json @@ -71,18 +71,10 @@ "district": "La Broye", "name": "Cheyres-Ch\u00e2bles" }, - "2061": { - "district": "La Gl\u00e2ne", - "name": "Auboranges" - }, "2063": { "district": "La Gl\u00e2ne", "name": "Billens-Hennens" }, - "2066": { - "district": "La Gl\u00e2ne", - "name": "Chapelle (Gl\u00e2ne)" - }, "2067": { "district": "La Gl\u00e2ne", "name": "Le Ch\u00e2telard" @@ -91,10 +83,6 @@ "district": "La Gl\u00e2ne", "name": "Ch\u00e2tonnaye" }, - "2072": { - "district": "La Gl\u00e2ne", - "name": "Ecublens (FR)" - }, "2079": { "district": "La Gl\u00e2ne", "name": "Grangettes" @@ -107,10 +95,6 @@ "district": "La Gl\u00e2ne", "name": "M\u00e9zi\u00e8res (FR)" }, - "2089": { - "district": "La Gl\u00e2ne", - "name": "Montet (Gl\u00e2ne)" - }, "2096": { "district": "La Gl\u00e2ne", "name": "Romont (FR)" @@ -283,10 +267,6 @@ "district": "La Sarine", "name": "Granges-Paccot" }, - "2200": { - "district": "La Sarine", - "name": "Grolley" - }, "2206": { "district": "La Sarine", "name": "Marly" @@ -303,10 +283,6 @@ "district": "La Sarine", "name": "Pierrafortscha" }, - "2217": { - "district": "La Sarine", - "name": "Ponthaux" - }, "2220": { "district": "La Sarine", "name": "Le Mouret" @@ -347,6 +323,10 @@ "district": "La Sarine", "name": "Bois-d'Amont" }, + "2239": { + "district": "La Sarine", + "name": "Grolley-Ponthaux" + }, "2250": { "district": "See / Lac", "name": "Courgevaux" diff --git a/src/onegov/election_day/static/municipalities/2025/gr.json b/src/onegov/election_day/static/municipalities/2025/gr.json index 4b02131b2f..daa3b34fe6 100644 --- a/src/onegov/election_day/static/municipalities/2025/gr.json +++ b/src/onegov/election_day/static/municipalities/2025/gr.json @@ -409,11 +409,6 @@ "name": "Arosa", "region": "Schanfigg" }, - "3932": { - "district": "Plessur", - "name": "Tschiertschen-Praden", - "region": "Churwalden" - }, "3945": { "district": "Landquart", "name": "Trimmis", diff --git a/src/onegov/election_day/static/municipalities/2025/lu.json b/src/onegov/election_day/static/municipalities/2025/lu.json index 1991c636cd..be789ba194 100644 --- a/src/onegov/election_day/static/municipalities/2025/lu.json +++ b/src/onegov/election_day/static/municipalities/2025/lu.json @@ -107,10 +107,6 @@ "district": "Luzern-Land", "name": "Greppen" }, - "1057": { - "district": "Luzern-Land", - "name": "Honau" - }, "1058": { "district": "Luzern-Land", "name": "Horw" diff --git a/src/onegov/election_day/static/municipalities/2025/ne.json b/src/onegov/election_day/static/municipalities/2025/ne.json index fded294a83..de4fd336b8 100644 --- a/src/onegov/election_day/static/municipalities/2025/ne.json +++ b/src/onegov/election_day/static/municipalities/2025/ne.json @@ -47,12 +47,6 @@ "6452": { "name": "Cressier (NE)" }, - "6453": { - "name": "Enges" - }, - "6454": { - "name": "Hauterive (NE)" - }, "6455": { "name": "Le Landeron" }, @@ -62,12 +56,6 @@ "6458": { "name": "Neuch\u00e2tel" }, - "6459": { - "name": "Saint-Blaise" - }, - "6461": { - "name": "La T\u00e8ne" - }, "6487": { "name": "Val-de-Ruz" }, @@ -79,5 +67,8 @@ }, "6512": { "name": "Val-de-Travers" + }, + "6513": { + "name": "Lat\u00e9na" } } \ No newline at end of file diff --git a/src/onegov/election_day/static/municipalities/2026/fr.json b/src/onegov/election_day/static/municipalities/2026/fr.json index f30827bfd1..1ae77481fd 100644 --- a/src/onegov/election_day/static/municipalities/2026/fr.json +++ b/src/onegov/election_day/static/municipalities/2026/fr.json @@ -71,18 +71,10 @@ "district": "La Broye", "name": "Cheyres-Ch\u00e2bles" }, - "2061": { - "district": "La Gl\u00e2ne", - "name": "Auboranges" - }, "2063": { "district": "La Gl\u00e2ne", "name": "Billens-Hennens" }, - "2066": { - "district": "La Gl\u00e2ne", - "name": "Chapelle (Gl\u00e2ne)" - }, "2067": { "district": "La Gl\u00e2ne", "name": "Le Ch\u00e2telard" @@ -91,10 +83,6 @@ "district": "La Gl\u00e2ne", "name": "Ch\u00e2tonnaye" }, - "2072": { - "district": "La Gl\u00e2ne", - "name": "Ecublens (FR)" - }, "2079": { "district": "La Gl\u00e2ne", "name": "Grangettes" @@ -107,10 +95,6 @@ "district": "La Gl\u00e2ne", "name": "M\u00e9zi\u00e8res (FR)" }, - "2089": { - "district": "La Gl\u00e2ne", - "name": "Montet (Gl\u00e2ne)" - }, "2096": { "district": "La Gl\u00e2ne", "name": "Romont (FR)" @@ -283,10 +267,6 @@ "district": "La Sarine", "name": "Granges-Paccot" }, - "2200": { - "district": "La Sarine", - "name": "Grolley" - }, "2206": { "district": "La Sarine", "name": "Marly" @@ -303,10 +283,6 @@ "district": "La Sarine", "name": "Pierrafortscha" }, - "2217": { - "district": "La Sarine", - "name": "Ponthaux" - }, "2220": { "district": "La Sarine", "name": "Le Mouret" @@ -347,6 +323,10 @@ "district": "La Sarine", "name": "Bois-d'Amont" }, + "2239": { + "district": "La Sarine", + "name": "Grolley-Ponthaux" + }, "2250": { "district": "See / Lac", "name": "Courgevaux" diff --git a/src/onegov/election_day/static/municipalities/2026/gr.json b/src/onegov/election_day/static/municipalities/2026/gr.json index 4b02131b2f..daa3b34fe6 100644 --- a/src/onegov/election_day/static/municipalities/2026/gr.json +++ b/src/onegov/election_day/static/municipalities/2026/gr.json @@ -409,11 +409,6 @@ "name": "Arosa", "region": "Schanfigg" }, - "3932": { - "district": "Plessur", - "name": "Tschiertschen-Praden", - "region": "Churwalden" - }, "3945": { "district": "Landquart", "name": "Trimmis", diff --git a/src/onegov/election_day/static/municipalities/2026/lu.json b/src/onegov/election_day/static/municipalities/2026/lu.json index 1991c636cd..be789ba194 100644 --- a/src/onegov/election_day/static/municipalities/2026/lu.json +++ b/src/onegov/election_day/static/municipalities/2026/lu.json @@ -107,10 +107,6 @@ "district": "Luzern-Land", "name": "Greppen" }, - "1057": { - "district": "Luzern-Land", - "name": "Honau" - }, "1058": { "district": "Luzern-Land", "name": "Horw" diff --git a/src/onegov/election_day/static/municipalities/2026/ne.json b/src/onegov/election_day/static/municipalities/2026/ne.json index fded294a83..de4fd336b8 100644 --- a/src/onegov/election_day/static/municipalities/2026/ne.json +++ b/src/onegov/election_day/static/municipalities/2026/ne.json @@ -47,12 +47,6 @@ "6452": { "name": "Cressier (NE)" }, - "6453": { - "name": "Enges" - }, - "6454": { - "name": "Hauterive (NE)" - }, "6455": { "name": "Le Landeron" }, @@ -62,12 +56,6 @@ "6458": { "name": "Neuch\u00e2tel" }, - "6459": { - "name": "Saint-Blaise" - }, - "6461": { - "name": "La T\u00e8ne" - }, "6487": { "name": "Val-de-Ruz" }, @@ -79,5 +67,8 @@ }, "6512": { "name": "Val-de-Travers" + }, + "6513": { + "name": "Lat\u00e9na" } } \ No newline at end of file diff --git a/src/onegov/election_day/static/municipalities/2027/fr.json b/src/onegov/election_day/static/municipalities/2027/fr.json index f30827bfd1..1ae77481fd 100644 --- a/src/onegov/election_day/static/municipalities/2027/fr.json +++ b/src/onegov/election_day/static/municipalities/2027/fr.json @@ -71,18 +71,10 @@ "district": "La Broye", "name": "Cheyres-Ch\u00e2bles" }, - "2061": { - "district": "La Gl\u00e2ne", - "name": "Auboranges" - }, "2063": { "district": "La Gl\u00e2ne", "name": "Billens-Hennens" }, - "2066": { - "district": "La Gl\u00e2ne", - "name": "Chapelle (Gl\u00e2ne)" - }, "2067": { "district": "La Gl\u00e2ne", "name": "Le Ch\u00e2telard" @@ -91,10 +83,6 @@ "district": "La Gl\u00e2ne", "name": "Ch\u00e2tonnaye" }, - "2072": { - "district": "La Gl\u00e2ne", - "name": "Ecublens (FR)" - }, "2079": { "district": "La Gl\u00e2ne", "name": "Grangettes" @@ -107,10 +95,6 @@ "district": "La Gl\u00e2ne", "name": "M\u00e9zi\u00e8res (FR)" }, - "2089": { - "district": "La Gl\u00e2ne", - "name": "Montet (Gl\u00e2ne)" - }, "2096": { "district": "La Gl\u00e2ne", "name": "Romont (FR)" @@ -283,10 +267,6 @@ "district": "La Sarine", "name": "Granges-Paccot" }, - "2200": { - "district": "La Sarine", - "name": "Grolley" - }, "2206": { "district": "La Sarine", "name": "Marly" @@ -303,10 +283,6 @@ "district": "La Sarine", "name": "Pierrafortscha" }, - "2217": { - "district": "La Sarine", - "name": "Ponthaux" - }, "2220": { "district": "La Sarine", "name": "Le Mouret" @@ -347,6 +323,10 @@ "district": "La Sarine", "name": "Bois-d'Amont" }, + "2239": { + "district": "La Sarine", + "name": "Grolley-Ponthaux" + }, "2250": { "district": "See / Lac", "name": "Courgevaux" diff --git a/src/onegov/election_day/static/municipalities/2027/gr.json b/src/onegov/election_day/static/municipalities/2027/gr.json index 4b02131b2f..daa3b34fe6 100644 --- a/src/onegov/election_day/static/municipalities/2027/gr.json +++ b/src/onegov/election_day/static/municipalities/2027/gr.json @@ -409,11 +409,6 @@ "name": "Arosa", "region": "Schanfigg" }, - "3932": { - "district": "Plessur", - "name": "Tschiertschen-Praden", - "region": "Churwalden" - }, "3945": { "district": "Landquart", "name": "Trimmis", diff --git a/src/onegov/election_day/static/municipalities/2027/lu.json b/src/onegov/election_day/static/municipalities/2027/lu.json index 1991c636cd..be789ba194 100644 --- a/src/onegov/election_day/static/municipalities/2027/lu.json +++ b/src/onegov/election_day/static/municipalities/2027/lu.json @@ -107,10 +107,6 @@ "district": "Luzern-Land", "name": "Greppen" }, - "1057": { - "district": "Luzern-Land", - "name": "Honau" - }, "1058": { "district": "Luzern-Land", "name": "Horw" diff --git a/src/onegov/election_day/static/municipalities/2027/ne.json b/src/onegov/election_day/static/municipalities/2027/ne.json index fded294a83..de4fd336b8 100644 --- a/src/onegov/election_day/static/municipalities/2027/ne.json +++ b/src/onegov/election_day/static/municipalities/2027/ne.json @@ -47,12 +47,6 @@ "6452": { "name": "Cressier (NE)" }, - "6453": { - "name": "Enges" - }, - "6454": { - "name": "Hauterive (NE)" - }, "6455": { "name": "Le Landeron" }, @@ -62,12 +56,6 @@ "6458": { "name": "Neuch\u00e2tel" }, - "6459": { - "name": "Saint-Blaise" - }, - "6461": { - "name": "La T\u00e8ne" - }, "6487": { "name": "Val-de-Ruz" }, @@ -79,5 +67,8 @@ }, "6512": { "name": "Val-de-Travers" + }, + "6513": { + "name": "Lat\u00e9na" } } \ No newline at end of file diff --git a/src/onegov/election_day/static/municipalities/2028/fr.json b/src/onegov/election_day/static/municipalities/2028/fr.json index f30827bfd1..1ae77481fd 100644 --- a/src/onegov/election_day/static/municipalities/2028/fr.json +++ b/src/onegov/election_day/static/municipalities/2028/fr.json @@ -71,18 +71,10 @@ "district": "La Broye", "name": "Cheyres-Ch\u00e2bles" }, - "2061": { - "district": "La Gl\u00e2ne", - "name": "Auboranges" - }, "2063": { "district": "La Gl\u00e2ne", "name": "Billens-Hennens" }, - "2066": { - "district": "La Gl\u00e2ne", - "name": "Chapelle (Gl\u00e2ne)" - }, "2067": { "district": "La Gl\u00e2ne", "name": "Le Ch\u00e2telard" @@ -91,10 +83,6 @@ "district": "La Gl\u00e2ne", "name": "Ch\u00e2tonnaye" }, - "2072": { - "district": "La Gl\u00e2ne", - "name": "Ecublens (FR)" - }, "2079": { "district": "La Gl\u00e2ne", "name": "Grangettes" @@ -107,10 +95,6 @@ "district": "La Gl\u00e2ne", "name": "M\u00e9zi\u00e8res (FR)" }, - "2089": { - "district": "La Gl\u00e2ne", - "name": "Montet (Gl\u00e2ne)" - }, "2096": { "district": "La Gl\u00e2ne", "name": "Romont (FR)" @@ -283,10 +267,6 @@ "district": "La Sarine", "name": "Granges-Paccot" }, - "2200": { - "district": "La Sarine", - "name": "Grolley" - }, "2206": { "district": "La Sarine", "name": "Marly" @@ -303,10 +283,6 @@ "district": "La Sarine", "name": "Pierrafortscha" }, - "2217": { - "district": "La Sarine", - "name": "Ponthaux" - }, "2220": { "district": "La Sarine", "name": "Le Mouret" @@ -347,6 +323,10 @@ "district": "La Sarine", "name": "Bois-d'Amont" }, + "2239": { + "district": "La Sarine", + "name": "Grolley-Ponthaux" + }, "2250": { "district": "See / Lac", "name": "Courgevaux" diff --git a/src/onegov/election_day/static/municipalities/2028/gr.json b/src/onegov/election_day/static/municipalities/2028/gr.json index 4b02131b2f..daa3b34fe6 100644 --- a/src/onegov/election_day/static/municipalities/2028/gr.json +++ b/src/onegov/election_day/static/municipalities/2028/gr.json @@ -409,11 +409,6 @@ "name": "Arosa", "region": "Schanfigg" }, - "3932": { - "district": "Plessur", - "name": "Tschiertschen-Praden", - "region": "Churwalden" - }, "3945": { "district": "Landquart", "name": "Trimmis", diff --git a/src/onegov/election_day/static/municipalities/2028/lu.json b/src/onegov/election_day/static/municipalities/2028/lu.json index 1991c636cd..be789ba194 100644 --- a/src/onegov/election_day/static/municipalities/2028/lu.json +++ b/src/onegov/election_day/static/municipalities/2028/lu.json @@ -107,10 +107,6 @@ "district": "Luzern-Land", "name": "Greppen" }, - "1057": { - "district": "Luzern-Land", - "name": "Honau" - }, "1058": { "district": "Luzern-Land", "name": "Horw" diff --git a/src/onegov/election_day/static/municipalities/2028/ne.json b/src/onegov/election_day/static/municipalities/2028/ne.json index fded294a83..de4fd336b8 100644 --- a/src/onegov/election_day/static/municipalities/2028/ne.json +++ b/src/onegov/election_day/static/municipalities/2028/ne.json @@ -47,12 +47,6 @@ "6452": { "name": "Cressier (NE)" }, - "6453": { - "name": "Enges" - }, - "6454": { - "name": "Hauterive (NE)" - }, "6455": { "name": "Le Landeron" }, @@ -62,12 +56,6 @@ "6458": { "name": "Neuch\u00e2tel" }, - "6459": { - "name": "Saint-Blaise" - }, - "6461": { - "name": "La T\u00e8ne" - }, "6487": { "name": "Val-de-Ruz" }, @@ -79,5 +67,8 @@ }, "6512": { "name": "Val-de-Travers" + }, + "6513": { + "name": "Lat\u00e9na" } } \ No newline at end of file diff --git a/src/onegov/election_day/static/municipalities/2029/fr.json b/src/onegov/election_day/static/municipalities/2029/fr.json index f30827bfd1..1ae77481fd 100644 --- a/src/onegov/election_day/static/municipalities/2029/fr.json +++ b/src/onegov/election_day/static/municipalities/2029/fr.json @@ -71,18 +71,10 @@ "district": "La Broye", "name": "Cheyres-Ch\u00e2bles" }, - "2061": { - "district": "La Gl\u00e2ne", - "name": "Auboranges" - }, "2063": { "district": "La Gl\u00e2ne", "name": "Billens-Hennens" }, - "2066": { - "district": "La Gl\u00e2ne", - "name": "Chapelle (Gl\u00e2ne)" - }, "2067": { "district": "La Gl\u00e2ne", "name": "Le Ch\u00e2telard" @@ -91,10 +83,6 @@ "district": "La Gl\u00e2ne", "name": "Ch\u00e2tonnaye" }, - "2072": { - "district": "La Gl\u00e2ne", - "name": "Ecublens (FR)" - }, "2079": { "district": "La Gl\u00e2ne", "name": "Grangettes" @@ -107,10 +95,6 @@ "district": "La Gl\u00e2ne", "name": "M\u00e9zi\u00e8res (FR)" }, - "2089": { - "district": "La Gl\u00e2ne", - "name": "Montet (Gl\u00e2ne)" - }, "2096": { "district": "La Gl\u00e2ne", "name": "Romont (FR)" @@ -283,10 +267,6 @@ "district": "La Sarine", "name": "Granges-Paccot" }, - "2200": { - "district": "La Sarine", - "name": "Grolley" - }, "2206": { "district": "La Sarine", "name": "Marly" @@ -303,10 +283,6 @@ "district": "La Sarine", "name": "Pierrafortscha" }, - "2217": { - "district": "La Sarine", - "name": "Ponthaux" - }, "2220": { "district": "La Sarine", "name": "Le Mouret" @@ -347,6 +323,10 @@ "district": "La Sarine", "name": "Bois-d'Amont" }, + "2239": { + "district": "La Sarine", + "name": "Grolley-Ponthaux" + }, "2250": { "district": "See / Lac", "name": "Courgevaux" diff --git a/src/onegov/election_day/static/municipalities/2029/gr.json b/src/onegov/election_day/static/municipalities/2029/gr.json index 4b02131b2f..daa3b34fe6 100644 --- a/src/onegov/election_day/static/municipalities/2029/gr.json +++ b/src/onegov/election_day/static/municipalities/2029/gr.json @@ -409,11 +409,6 @@ "name": "Arosa", "region": "Schanfigg" }, - "3932": { - "district": "Plessur", - "name": "Tschiertschen-Praden", - "region": "Churwalden" - }, "3945": { "district": "Landquart", "name": "Trimmis", diff --git a/src/onegov/election_day/static/municipalities/2029/lu.json b/src/onegov/election_day/static/municipalities/2029/lu.json index 1991c636cd..be789ba194 100644 --- a/src/onegov/election_day/static/municipalities/2029/lu.json +++ b/src/onegov/election_day/static/municipalities/2029/lu.json @@ -107,10 +107,6 @@ "district": "Luzern-Land", "name": "Greppen" }, - "1057": { - "district": "Luzern-Land", - "name": "Honau" - }, "1058": { "district": "Luzern-Land", "name": "Horw" diff --git a/src/onegov/election_day/static/municipalities/2029/ne.json b/src/onegov/election_day/static/municipalities/2029/ne.json index fded294a83..de4fd336b8 100644 --- a/src/onegov/election_day/static/municipalities/2029/ne.json +++ b/src/onegov/election_day/static/municipalities/2029/ne.json @@ -47,12 +47,6 @@ "6452": { "name": "Cressier (NE)" }, - "6453": { - "name": "Enges" - }, - "6454": { - "name": "Hauterive (NE)" - }, "6455": { "name": "Le Landeron" }, @@ -62,12 +56,6 @@ "6458": { "name": "Neuch\u00e2tel" }, - "6459": { - "name": "Saint-Blaise" - }, - "6461": { - "name": "La T\u00e8ne" - }, "6487": { "name": "Val-de-Ruz" }, @@ -79,5 +67,8 @@ }, "6512": { "name": "Val-de-Travers" + }, + "6513": { + "name": "Lat\u00e9na" } } \ No newline at end of file diff --git a/src/onegov/election_day/static/municipalities/2030/fr.json b/src/onegov/election_day/static/municipalities/2030/fr.json index f30827bfd1..1ae77481fd 100644 --- a/src/onegov/election_day/static/municipalities/2030/fr.json +++ b/src/onegov/election_day/static/municipalities/2030/fr.json @@ -71,18 +71,10 @@ "district": "La Broye", "name": "Cheyres-Ch\u00e2bles" }, - "2061": { - "district": "La Gl\u00e2ne", - "name": "Auboranges" - }, "2063": { "district": "La Gl\u00e2ne", "name": "Billens-Hennens" }, - "2066": { - "district": "La Gl\u00e2ne", - "name": "Chapelle (Gl\u00e2ne)" - }, "2067": { "district": "La Gl\u00e2ne", "name": "Le Ch\u00e2telard" @@ -91,10 +83,6 @@ "district": "La Gl\u00e2ne", "name": "Ch\u00e2tonnaye" }, - "2072": { - "district": "La Gl\u00e2ne", - "name": "Ecublens (FR)" - }, "2079": { "district": "La Gl\u00e2ne", "name": "Grangettes" @@ -107,10 +95,6 @@ "district": "La Gl\u00e2ne", "name": "M\u00e9zi\u00e8res (FR)" }, - "2089": { - "district": "La Gl\u00e2ne", - "name": "Montet (Gl\u00e2ne)" - }, "2096": { "district": "La Gl\u00e2ne", "name": "Romont (FR)" @@ -283,10 +267,6 @@ "district": "La Sarine", "name": "Granges-Paccot" }, - "2200": { - "district": "La Sarine", - "name": "Grolley" - }, "2206": { "district": "La Sarine", "name": "Marly" @@ -303,10 +283,6 @@ "district": "La Sarine", "name": "Pierrafortscha" }, - "2217": { - "district": "La Sarine", - "name": "Ponthaux" - }, "2220": { "district": "La Sarine", "name": "Le Mouret" @@ -347,6 +323,10 @@ "district": "La Sarine", "name": "Bois-d'Amont" }, + "2239": { + "district": "La Sarine", + "name": "Grolley-Ponthaux" + }, "2250": { "district": "See / Lac", "name": "Courgevaux" diff --git a/src/onegov/election_day/static/municipalities/2030/gr.json b/src/onegov/election_day/static/municipalities/2030/gr.json index 4b02131b2f..daa3b34fe6 100644 --- a/src/onegov/election_day/static/municipalities/2030/gr.json +++ b/src/onegov/election_day/static/municipalities/2030/gr.json @@ -409,11 +409,6 @@ "name": "Arosa", "region": "Schanfigg" }, - "3932": { - "district": "Plessur", - "name": "Tschiertschen-Praden", - "region": "Churwalden" - }, "3945": { "district": "Landquart", "name": "Trimmis", diff --git a/src/onegov/election_day/static/municipalities/2030/lu.json b/src/onegov/election_day/static/municipalities/2030/lu.json index 1991c636cd..be789ba194 100644 --- a/src/onegov/election_day/static/municipalities/2030/lu.json +++ b/src/onegov/election_day/static/municipalities/2030/lu.json @@ -107,10 +107,6 @@ "district": "Luzern-Land", "name": "Greppen" }, - "1057": { - "district": "Luzern-Land", - "name": "Honau" - }, "1058": { "district": "Luzern-Land", "name": "Horw" diff --git a/src/onegov/election_day/static/municipalities/2030/ne.json b/src/onegov/election_day/static/municipalities/2030/ne.json index fded294a83..de4fd336b8 100644 --- a/src/onegov/election_day/static/municipalities/2030/ne.json +++ b/src/onegov/election_day/static/municipalities/2030/ne.json @@ -47,12 +47,6 @@ "6452": { "name": "Cressier (NE)" }, - "6453": { - "name": "Enges" - }, - "6454": { - "name": "Hauterive (NE)" - }, "6455": { "name": "Le Landeron" }, @@ -62,12 +56,6 @@ "6458": { "name": "Neuch\u00e2tel" }, - "6459": { - "name": "Saint-Blaise" - }, - "6461": { - "name": "La T\u00e8ne" - }, "6487": { "name": "Val-de-Ruz" }, @@ -79,5 +67,8 @@ }, "6512": { "name": "Val-de-Travers" + }, + "6513": { + "name": "Lat\u00e9na" } } \ No newline at end of file diff --git a/src/onegov/election_day/static/quarters/2025/351.json b/src/onegov/election_day/static/quarters/2025/351.json new file mode 100644 index 0000000000..5470bee620 --- /dev/null +++ b/src/onegov/election_day/static/quarters/2025/351.json @@ -0,0 +1,20 @@ +{ + "1": { + "name": "Innere Stadt" + }, + "2": { + "name": "L\u00e4nggasse/Felsenau" + }, + "3": { + "name": "Mattenhof/Weissenb\u00fchl" + }, + "4": { + "name": "Kirchenfeld/Schosshalde" + }, + "5": { + "name": "Breitenrain/Lorraine" + }, + "6": { + "name": "B\u00fcmpliz/Bethlehem" + } +} diff --git a/src/onegov/election_day/theme/__init__.py b/src/onegov/election_day/theme/__init__.py index 9b32b67939..c016ffde3d 100644 --- a/src/onegov/election_day/theme/__init__.py +++ b/src/onegov/election_day/theme/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.theme.election_day_theme import ElectionDayTheme __all__ = ( diff --git a/src/onegov/election_day/theme/election_day_theme.py b/src/onegov/election_day/theme/election_day_theme.py index 8750f56888..11bf545389 100644 --- a/src/onegov/election_day/theme/election_day_theme.py +++ b/src/onegov/election_day/theme/election_day_theme.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.foundation import BaseTheme from onegov.core.utils import module_path @@ -22,7 +24,7 @@ def default_options(self) -> dict[str, Any]: # Leave this empty, see below return {} - def compile(self, options: 'Mapping[str, Any] | None' = None) -> str: + def compile(self, options: Mapping[str, Any] | None = None) -> str: # We cannot use the default_options attribute since we need to know # the primary color which happens to be in the options argument. # We merge the options and default options ourselve and call the diff --git a/src/onegov/election_day/types.py b/src/onegov/election_day/types.py index 9b45b0e81d..69520116a9 100644 --- a/src/onegov/election_day/types.py +++ b/src/onegov/election_day/types.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import TYPE_CHECKING if TYPE_CHECKING: from onegov.core.types import JSONObject diff --git a/src/onegov/election_day/upgrade.py b/src/onegov/election_day/upgrade.py index 11ca9a7855..2a7087059b 100644 --- a/src/onegov/election_day/upgrade.py +++ b/src/onegov/election_day/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + from onegov.core.orm.types import HSTORE from onegov.core.orm.types import JSON from onegov.core.orm.types import UTCDateTime diff --git a/src/onegov/election_day/utils/__init__.py b/src/onegov/election_day/utils/__init__.py index 777ac31737..a70a5ad2ca 100644 --- a/src/onegov/election_day/utils/__init__.py +++ b/src/onegov/election_day/utils/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.utils.common import add_cors_header from onegov.election_day.utils.common import add_last_modified_header from onegov.election_day.utils.common import add_local_results diff --git a/src/onegov/election_day/utils/archive_generator.py b/src/onegov/election_day/utils/archive_generator.py index 51551f676a..21657cad52 100644 --- a/src/onegov/election_day/utils/archive_generator.py +++ b/src/onegov/election_day/utils/archive_generator.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import defaultdict from fs import path from fs.copy import copy_dir @@ -39,9 +41,9 @@ class ArchiveGenerator: This creates a bunch of csv files, which are zipped and the path to the zip is returned. """ - archive_dir: 'SubFS[FS]' + archive_dir: SubFS[FS] - def __init__(self, app: 'ElectionDayApp'): + def __init__(self, app: ElectionDayApp): assert app.filestorage is not None self.app = app self.session = app.session() @@ -97,7 +99,7 @@ def generate_csv(self) -> None: def get_all_rows_for_votes( self, - votes: 'Collection[Vote]' + votes: Collection[Vote] ) -> list[dict[str, Any]]: locales = sorted(self.app.locales) @@ -109,8 +111,8 @@ def get_all_rows_for_votes( def group_by_year( self, - entities: 'Iterable[EntityT]' - ) -> list[list['EntityT']]: + entities: Iterable[EntityT] + ) -> list[list[EntityT]]: """Creates a list of lists, grouped by year. :param entities: Iterable of entities @@ -133,7 +135,7 @@ def group_by_year( groups[entity.date.year].append(entity) return list(groups.values()) - def zip_dir(self, base_dir: 'SubFS[FS]') -> str | None: + def zip_dir(self, base_dir: SubFS[FS]) -> str | None: """Recursively zips a directory (base_dir). :param base_dir: is a directory in a temporary file system. @@ -192,8 +194,8 @@ def all_counted_election_compounds_with_results( def filter_by_final_results( self, - all_entities: 'Iterable[EntityT]' - ) -> list['EntityT']: + all_entities: Iterable[EntityT] + ) -> list[EntityT]: return [ entity @@ -223,7 +225,7 @@ def include_docs(self) -> None: dst_path=match.path, ) - def export_item(self, item: 'EntityT', dir: str) -> None: + def export_item(self, item: EntityT, dir: str) -> None: locales = sorted(self.app.locales) assert self.app.default_locale default_locale = self.app.default_locale diff --git a/src/onegov/election_day/utils/common.py b/src/onegov/election_day/utils/common.py index 7b130107bf..5b244d40d0 100644 --- a/src/onegov/election_day/utils/common.py +++ b/src/onegov/election_day/utils/common.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from onegov.core.utils import append_query_param from onegov.election_day import _ @@ -56,8 +58,8 @@ def __setitem__(self, key: _KT, value: _VT) -> None: def add_last_modified_header( - response: 'Response', - last_modified: 'datetime | None' + response: Response, + last_modified: datetime | None ) -> None: """ Adds the give date to the response as Last-Modified header. """ @@ -68,16 +70,16 @@ def add_last_modified_header( ) -def add_cors_header(response: 'Response') -> None: +def add_cors_header(response: Response) -> None: """ Adds a header allowing the response being used in scripts. """ response.headers.add('Access-Control-Allow-Origin', '*') def add_local_results( - source: 'ArchivedResult', - target: 'ArchivedResult', - principal: 'Canton | Municipality', - session: 'Session' + source: ArchivedResult, + target: ArchivedResult, + principal: Canton | Municipality, + session: Session ) -> None: """ Adds the result of the principal. @@ -147,7 +149,7 @@ def add_local_results( def get_parameter( - request: 'ElectionDayRequest', + request: ElectionDayRequest, name: str, type_: type[_ParamT], default: _T @@ -183,8 +185,8 @@ def get_parameter( def get_entity_filter( - request: 'ElectionDayRequest', - item: 'Election', + request: ElectionDayRequest, + item: Election, view: str, selected: str | None ) -> list[tuple[str, bool, str]]: diff --git a/src/onegov/election_day/utils/d3_renderer.py b/src/onegov/election_day/utils/d3_renderer.py index d98b2ecb3a..ded7f427ef 100644 --- a/src/onegov/election_day/utils/d3_renderer.py +++ b/src/onegov/election_day/utils/d3_renderer.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from base64 import b64decode from io import BytesIO from io import StringIO @@ -41,7 +43,7 @@ class D3Renderer: """ - def __init__(self, app: 'ElectionDayApp'): + def __init__(self, app: ElectionDayApp): self.app = app self.renderer = app.configuration.get('d3_renderer', '').rstrip('/') self.supported_charts = { @@ -78,7 +80,7 @@ def __init__(self, app: 'ElectionDayApp'): with open(path) as f: self.scripts[chart].append(jsmin(f.read())) - def translate(self, text: 'TranslationString', locale: str | None) -> str: + def translate(self, text: TranslationString, locale: str | None) -> str: """ Translates the given string. """ if locale is not None: @@ -95,7 +97,7 @@ def get_chart( self, chart: str, fmt: Literal['pdf'], - data: 'JSON_ro', + data: JSON_ro, width: int = 1000, params: dict[str, Any] | None = None ) -> IO[bytes]: ... @@ -105,7 +107,7 @@ def get_chart( self, chart: str, fmt: Literal['svg'], - data: 'JSON_ro', + data: JSON_ro, width: int = 1000, params: dict[str, Any] | None = None ) -> IO[str]: ... @@ -115,7 +117,7 @@ def get_chart( self, chart: str, fmt: Literal['pdf', 'svg'], - data: 'JSON_ro', + data: JSON_ro, width: int = 1000, params: dict[str, Any] | None = None ) -> IO[str] | IO[bytes]: ... @@ -124,7 +126,7 @@ def get_chart( self, chart: str, fmt: Literal['pdf', 'svg'], - data: 'JSON_ro', + data: JSON_ro, width: int = 1000, params: dict[str, Any] | None = None ) -> IO[str] | IO[bytes]: @@ -165,7 +167,7 @@ def get_map( self, map: str, fmt: Literal['pdf'], - data: 'JSON_ro', + data: JSON_ro, year: int, width: int = 1000, params: dict[str, Any] | None = None @@ -176,7 +178,7 @@ def get_map( self, map: str, fmt: Literal['svg'], - data: 'JSON_ro', + data: JSON_ro, year: int, width: int = 1000, params: dict[str, Any] | None = None @@ -187,7 +189,7 @@ def get_map( self, map: str, fmt: Literal['svg', 'pdf'], - data: 'JSON_ro', + data: JSON_ro, year: int, width: int = 1000, params: dict[str, Any] | None = None @@ -197,7 +199,7 @@ def get_map( self, map: str, fmt: Literal['pdf', 'svg'], - data: 'JSON_ro', + data: JSON_ro, year: int, width: int = 1000, params: dict[str, Any] | None = None diff --git a/src/onegov/election_day/utils/election/__init__.py b/src/onegov/election_day/utils/election/__init__.py index b8a8bee5be..43edd340b4 100644 --- a/src/onegov/election_day/utils/election/__init__.py +++ b/src/onegov/election_day/utils/election/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.utils.election.candidates import get_candidates_data from onegov.election_day.utils.election.candidates import ( get_candidates_results) diff --git a/src/onegov/election_day/utils/election/candidates.py b/src/onegov/election_day/utils/election/candidates.py index 37ae28b520..ec2fbeb5b4 100644 --- a/src/onegov/election_day/utils/election/candidates.py +++ b/src/onegov/election_day/utils/election/candidates.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import groupbylist from onegov.election_day.models import Candidate from onegov.election_day.models import CandidateResult @@ -49,10 +51,10 @@ class ResultRow(NamedTuple): def get_candidates_results( - election: 'Election', - session: 'Session', - entities: 'Collection[str] | None' = None, -) -> 'Query[CandidateResultRow]': + election: Election, + session: Session, + entities: Collection[str] | None = None, +) -> Query[CandidateResultRow]: """ Returns the aggregated candidates results as list. Also includes percentages of votes for majorz elections. Be aware that this @@ -125,13 +127,13 @@ def get_candidates_results( def get_candidates_data( - election: 'Election', + election: Election, limit: int | None = None, - lists: 'Collection[str] | None' = None, + lists: Collection[str] | None = None, elected: bool | None = None, sort_by_lists: bool = False, - entities: 'Collection[str] | None' = None -) -> 'JSONObject_ro': + entities: Collection[str] | None = None +) -> JSONObject_ro: """" Get the candidates as JSON. Used to for the candidates bar chart. Allows to optionally @@ -246,9 +248,9 @@ def get_candidates_data( def get_candidates_results_by_entity( - election: 'Election', + election: Election, sort_by_votes: bool = False -) -> tuple[list['CandidateRow'], list[tuple[str, list['ResultRow']]]]: +) -> tuple[list[CandidateRow], list[tuple[str, list[ResultRow]]]]: """ Returns the candidates results by entity. Allows to optionally order by the number of total votes instead of the diff --git a/src/onegov/election_day/utils/election/connections.py b/src/onegov/election_day/utils/election/connections.py index 3f693d5f64..bf4073ae0f 100644 --- a/src/onegov/election_day/utils/election/connections.py +++ b/src/onegov/election_day/utils/election/connections.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from itertools import groupby from onegov.core.orm import as_selectable_from_path @@ -34,9 +36,9 @@ def to_int(value: str) -> int | str: def get_connection_results_api( - election: 'Election', - session: 'Session' -) -> 'JSONObject_ro': + election: Election, + session: Session +) -> JSONObject_ro: connection_query = as_selectable_from_path( module_path( @@ -77,9 +79,9 @@ def get_connection_results_api( def get_connection_results( - election: 'Election', - session: 'Session' -) -> list['Connection']: + election: Election, + session: Session +) -> list[Connection]: """ Returns the aggregated list connection results as list. """ if election.type != 'proporz': @@ -151,8 +153,8 @@ def get_connection_results( def get_connections_data( - election: 'Election', -) -> 'JSONObject_ro': + election: Election, +) -> JSONObject_ro: """" View the list connections as JSON. Used to for the connection sankey chart. """ diff --git a/src/onegov/election_day/utils/election/lists.py b/src/onegov/election_day/utils/election/lists.py index fff40547fa..02d5fd322a 100644 --- a/src/onegov/election_day/utils/election/lists.py +++ b/src/onegov/election_day/utils/election/lists.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from onegov.election_day import _ from onegov.election_day.models import ElectionResult @@ -31,12 +33,12 @@ class ListResultRow(NamedTuple): def get_list_results( - election: 'Election', + election: Election, limit: int | None = None, - names: 'Collection[str] | None' = None, + names: Collection[str] | None = None, sort_by_names: bool = False, - entities: 'Collection[str] | None' = None -) -> 'Query[ListResultRow]': + entities: Collection[str] | None = None +) -> Query[ListResultRow]: """ Returns the aggregated list results as list. """ session = object_session(election) @@ -80,13 +82,13 @@ def get_list_results( def get_lists_data( - election: 'Election', + election: Election, limit: int | None = None, - names: 'Collection[str] | None' = None, + names: Collection[str] | None = None, mandates_only: bool = False, sort_by_names: bool = False, - entities: 'Collection[str] | None' = None -) -> 'JSONObject_ro': + entities: Collection[str] | None = None +) -> JSONObject_ro: """" View the lists as JSON. Used to for the lists bar chart. """ allocated_mandates = election.allocated_mandates @@ -126,9 +128,9 @@ def get_lists_data( def get_lists_panachage_data( - election: 'Election', - request: 'ElectionDayRequest | None' -) -> 'JSONObject_ro': + election: Election, + request: ElectionDayRequest | None +) -> JSONObject_ro: """" Get the panachage data as JSON. Used to for the panachage sankey chart. diff --git a/src/onegov/election_day/utils/election_compound/__init__.py b/src/onegov/election_day/utils/election_compound/__init__.py index 4fbeb61d87..ac93cb94f0 100644 --- a/src/onegov/election_day/utils/election_compound/__init__.py +++ b/src/onegov/election_day/utils/election_compound/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.utils.election_compound.candidates import ( get_candidate_statistics) from onegov.election_day.utils.election_compound.candidates import ( diff --git a/src/onegov/election_day/utils/election_compound/candidates.py b/src/onegov/election_day/utils/election_compound/candidates.py index ed0af7d66a..16ea0de673 100644 --- a/src/onegov/election_day/utils/election_compound/candidates.py +++ b/src/onegov/election_day/utils/election_compound/candidates.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import groupbylist from onegov.election_day.models import Candidate from onegov.election_day.models import Election @@ -34,9 +36,9 @@ class CandidateStatistics(TypedDict): def get_elected_candidates( - election_compound: 'ElectionCompound | ElectionCompoundPart', - session: 'Session' -) -> 'Query[ElectedCandidateRow]': + election_compound: ElectionCompound | ElectionCompoundPart, + session: Session +) -> Query[ElectedCandidateRow]: """ Returns the elected candidates of an election compound. """ election_ids = [election.id for election in election_compound.elections] @@ -66,9 +68,9 @@ def get_elected_candidates( def get_candidate_statistics( - election_compound: 'ElectionCompound | ElectionCompoundPart', - elected_candidates: 'Iterable[ElectedCandidateRow] | None' = None -) -> dict[str, 'CandidateStatistics']: + election_compound: ElectionCompound | ElectionCompoundPart, + elected_candidates: Iterable[ElectedCandidateRow] | None = None +) -> dict[str, CandidateStatistics]: if elected_candidates is None: session = object_session(election_compound) @@ -77,8 +79,8 @@ def get_candidate_statistics( year = election_compound.date.year def statistics( - values: list[tuple['Gender', int | None]] - ) -> 'CandidateStatistics': + values: list[tuple[Gender, int | None]] + ) -> CandidateStatistics: birth_years = [ birth_year diff --git a/src/onegov/election_day/utils/election_compound/districts.py b/src/onegov/election_day/utils/election_compound/districts.py index da04a79380..58e742abb7 100644 --- a/src/onegov/election_day/utils/election_compound/districts.py +++ b/src/onegov/election_day/utils/election_compound/districts.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import groupbylist from operator import itemgetter @@ -13,10 +15,10 @@ def get_districts_data( - compound: 'ElectionCompound | ElectionCompoundPart', - principal: 'Canton | Municipality', - request: 'ElectionDayRequest | None' = None -) -> 'JSONObject_ro': + compound: ElectionCompound | ElectionCompoundPart, + principal: Canton | Municipality, + request: ElectionDayRequest | None = None +) -> JSONObject_ro: """ Returns the data used by elections compounds for rendering entities and districts maps. """ diff --git a/src/onegov/election_day/utils/election_compound/list_groups.py b/src/onegov/election_day/utils/election_compound/list_groups.py index df9cc2dee6..33ebd1c401 100644 --- a/src/onegov/election_day/utils/election_compound/list_groups.py +++ b/src/onegov/election_day/utils/election_compound/list_groups.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import NamedTuple, TYPE_CHECKING if TYPE_CHECKING: @@ -9,19 +11,19 @@ class ListGroupsRow(NamedTuple): name: str | None - voters_count: 'Decimal | int | None' + voters_count: Decimal | int | None number_of_mandates: int def get_list_groups( - election_compound: 'ElectionCompound' + election_compound: ElectionCompound ) -> list[ListGroupsRow]: """" Get list groups data. """ if not election_compound.pukelsheim: return [] - def get_voters_count(result: 'PartyResult') -> 'Decimal | int | None': + def get_voters_count(result: PartyResult) -> Decimal | int | None: if result.voters_count is None: return result.voters_count if election_compound.exact_voters_counts: @@ -44,8 +46,8 @@ def get_voters_count(result: 'PartyResult') -> 'Decimal | int | None': def get_list_groups_data( - election_compound: 'ElectionCompound' -) -> 'JSONObject_ro': + election_compound: ElectionCompound +) -> JSONObject_ro: """" Get the list groups bar chart data as JSON. """ results = get_list_groups(election_compound) diff --git a/src/onegov/election_day/utils/election_compound/superregions.py b/src/onegov/election_day/utils/election_compound/superregions.py index 27a37737eb..1de88cc28c 100644 --- a/src/onegov/election_day/utils/election_compound/superregions.py +++ b/src/onegov/election_day/utils/election_compound/superregions.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models import ElectionCompoundPart @@ -18,9 +20,9 @@ class SuperregionInfo(TypedDict): def get_superregions( - compound: 'ElectionCompound', - principal: 'Canton | Municipality' -) -> dict[str, 'SuperregionInfo']: + compound: ElectionCompound, + principal: Canton | Municipality +) -> dict[str, SuperregionInfo]: """ Returns all superregions. """ if compound.domain_elections != 'region': @@ -57,10 +59,10 @@ def get_superregions( def get_superregions_data( - compound: 'ElectionCompound', - principal: 'Canton | Municipality', - request: 'ElectionDayRequest | None' = None -) -> 'JSONObject_ro': + compound: ElectionCompound, + principal: Canton | Municipality, + request: ElectionDayRequest | None = None +) -> JSONObject_ro: """ Returns the data used by elections compounds for rendering entities and districts maps. """ diff --git a/src/onegov/election_day/utils/filenames.py b/src/onegov/election_day/utils/filenames.py index ce973b660d..45afa1e359 100644 --- a/src/onegov/election_day/utils/filenames.py +++ b/src/onegov/election_day/utils/filenames.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from hashlib import sha256 from onegov.election_day.models import Ballot from onegov.election_day.models import Election @@ -26,7 +28,7 @@ def filename_prefix(item: object) -> str: def pdf_filename( item: Ballot | Vote | Election | ElectionCompound | ElectionCompoundPart, locale: str, - last_modified: 'datetime | None' = None + last_modified: datetime | None = None ) -> str: """ Generates a filename from an election or vote: @@ -52,7 +54,7 @@ def svg_filename( item: Ballot | Vote | Election | ElectionCompound | ElectionCompoundPart, type_: str | None, locale: str, - last_modified: 'datetime | None' = None + last_modified: datetime | None = None ) -> str: """ Generates a filename from an election, ballot or vote: diff --git a/src/onegov/election_day/utils/notification.py b/src/onegov/election_day/utils/notification.py index ef4c5f6658..b3a7ca7e92 100644 --- a/src/onegov/election_day/utils/notification.py +++ b/src/onegov/election_day/utils/notification.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from itertools import chain from onegov.election_day.models.subscriber import Subscriber from sqlalchemy import and_ @@ -18,18 +20,18 @@ class ModelGroup(NamedTuple): - domain: 'DomainSubset' + domain: DomainSubset domain_segment: str | None - elections: 'Sequence[Election]' - election_compounds: 'Sequence[ElectionCompound]' - votes: 'Sequence[Vote]' - filter: 'ColumnElement[bool]' + elections: Sequence[Election] + election_compounds: Sequence[ElectionCompound] + votes: Sequence[Vote] + filter: ColumnElement[bool] def segment_models( - elections: 'Sequence[Election]', - election_compounds: 'Sequence[ElectionCompound]', - votes: 'Sequence[Vote]' + elections: Sequence[Election], + election_compounds: Sequence[ElectionCompound], + votes: Sequence[Vote] ) -> list[ModelGroup]: """ Group elections, compounds and votes by subscribable notification segmenation. @@ -52,8 +54,8 @@ def segment_models( } def match_( - model: 'Election | ElectionCompound | Vote', - domain: 'DomainSubset', + model: Election | ElectionCompound | Vote, + domain: DomainSubset, domain_segment: str | None ) -> bool: if domain != 'municipality': diff --git a/src/onegov/election_day/utils/parties/__init__.py b/src/onegov/election_day/utils/parties/__init__.py index 2d10fe46f3..ef1f8da715 100644 --- a/src/onegov/election_day/utils/parties/__init__.py +++ b/src/onegov/election_day/utils/parties/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.utils.parties.parties import get_party_results from onegov.election_day.utils.parties.parties import get_party_results_deltas from onegov.election_day.utils.parties.parties import get_party_results_data diff --git a/src/onegov/election_day/utils/parties/parties.py b/src/onegov/election_day/utils/parties/parties.py index 756f6d3dea..b1489dd763 100644 --- a/src/onegov/election_day/utils/parties/parties.py +++ b/src/onegov/election_day/utils/parties/parties.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from decimal import Decimal from onegov.election_day import _ from operator import itemgetter @@ -17,7 +19,7 @@ def get_party_results( - item: 'Election | ElectionCompound | ElectionCompoundPart', + item: Election | ElectionCompound | ElectionCompoundPart, json_serializable: bool = False ) -> tuple[list[str], dict[str, Any]]: @@ -86,8 +88,8 @@ def get_party_results( def get_party_results_deltas( - item: 'Election | ElectionCompound | ElectionCompoundPart', - years: 'Sequence[str]', + item: Election | ElectionCompound | ElectionCompoundPart, + years: Sequence[str], parties: dict[str, Any] ) -> tuple[bool, dict[str, list[list[str]]]]: @@ -135,9 +137,9 @@ def get_party_results_deltas( def get_party_results_data( - item: 'Election | ElectionCompound | ElectionCompoundPart', + item: Election | ElectionCompound | ElectionCompoundPart, horizontal: bool -) -> 'JSONObject_ro': +) -> JSONObject_ro: """ Retuns the data used for the diagrams showing the party results. """ if horizontal: return get_party_results_horizontal_data(item) @@ -145,8 +147,8 @@ def get_party_results_data( def get_party_results_horizontal_data( - item: 'Election | ElectionCompound | ElectionCompoundPart' -) -> 'JSONObject_ro': + item: Election | ElectionCompound | ElectionCompoundPart +) -> JSONObject_ro: """ Retuns the data used for the horitzonal bar diagram showing the party results. @@ -210,8 +212,8 @@ def get_party_results_horizontal_data( def get_party_results_vertical_data( - item: 'Election | ElectionCompound | ElectionCompoundPart' -) -> 'JSONObject_ro': + item: Election | ElectionCompound | ElectionCompoundPart +) -> JSONObject_ro: """ Retuns the data used for the grouped bar diagram showing the party results. @@ -269,7 +271,7 @@ def get_party_results_vertical_data( def get_party_results_seat_allocation( - years: 'Sequence[str]', + years: Sequence[str], parties: dict[str, Any] ) -> list[list[Any]]: @@ -298,9 +300,9 @@ def get_party_results_seat_allocation( def get_parties_panachage_data( - item: 'Election | ElectionCompound | ElectionCompoundPart', - request: 'ElectionDayRequest | None' = None -) -> 'JSONObject_ro': + item: Election | ElectionCompound | ElectionCompoundPart, + request: ElectionDayRequest | None = None +) -> JSONObject_ro: """" Get the panachage data as JSON. Used to for the panachage sankey chart. diff --git a/src/onegov/election_day/utils/pdf_generator.py b/src/onegov/election_day/utils/pdf_generator.py index d3925adcfb..4a7b3fc19a 100644 --- a/src/onegov/election_day/utils/pdf_generator.py +++ b/src/onegov/election_day/utils/pdf_generator.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os.path from onegov.election_day import _ @@ -48,8 +50,8 @@ class PdfGenerator: def __init__( self, - app: 'ElectionDayApp', - request: 'ElectionDayRequest', + app: ElectionDayApp, + request: ElectionDayRequest, renderer: D3Renderer | None = None ): self.app = app @@ -58,7 +60,7 @@ def __init__( self.session = self.app.session() self.renderer = renderer or D3Renderer(app) - def remove(self, directory: str, files: 'Collection[str]') -> None: + def remove(self, directory: str, files: Collection[str]) -> None: """ Safely removes the given files from the directory. """ if not files: return @@ -136,7 +138,7 @@ def generate_pdf( def add_tacit_election( self, - principal: 'Canton | Municipality', + principal: Canton | Municipality, election: Election, pdf: Pdf ) -> None: @@ -173,12 +175,12 @@ def add_tacit_election( def add_election( self, - principal: 'Canton | Municipality', + principal: Canton | Municipality, election: Election, pdf: Pdf ) -> None: - def format_name(item: 'ElectionResult') -> str: + def format_name(item: ElectionResult) -> str: return item.name if item.entity_id else pdf.translate(_('Expats')) majorz = election.type == 'majorz' @@ -469,7 +471,7 @@ def format_name(item: 'ElectionResult') -> str: def add_election_compound( self, - principal: 'Canton | Municipality', + principal: Canton | Municipality, compound: ElectionCompound, pdf: Pdf ) -> None: @@ -777,7 +779,7 @@ def format_gender(value: str) -> str: def add_vote( self, - principal: 'Canton | Municipality', + principal: Canton | Municipality, vote: Vote, pdf: Pdf, locale: str @@ -788,7 +790,7 @@ def add_vote( layout = VoteLayout(vote, self.request) direct = vote.direct - def format_name(item: 'BallotResult | ResultsByDistrictRow') -> str: + def format_name(item: BallotResult | ResultsByDistrictRow) -> str: if getattr(item, 'entity_id', None): # FIXME: Why are we even doing this check, when we still # return the name rather than the entity_id? Is @@ -799,8 +801,8 @@ def format_name(item: 'BallotResult | ResultsByDistrictRow') -> str: return pdf.translate(_('Expats')) def format_accepted( - result: 'BallotResult | Ballot | ResultsByDistrictRow', - ballot: 'Ballot' + result: BallotResult | Ballot | ResultsByDistrictRow, + ballot: Ballot ) -> str: tie_breaker = ( ballot.type == 'tie-breaker' @@ -824,9 +826,9 @@ def format_percentage(number: float) -> str: return f'{number:.2f}%' def format_value( - result: 'Ballot | BallotResult | ResultsByDistrictRow', + result: Ballot | BallotResult | ResultsByDistrictRow, attr: str, - fmt: 'Callable[[Any], str]' = format_percentage + fmt: Callable[[Any], str] = format_percentage ) -> str: if result.accepted is None: diff --git a/src/onegov/election_day/utils/summaries.py b/src/onegov/election_day/utils/summaries.py index 11821ac65b..9ad8f64d47 100644 --- a/src/onegov/election_day/utils/summaries.py +++ b/src/onegov/election_day/utils/summaries.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.models import ArchivedResult from onegov.election_day.models import Election from onegov.election_day.models import ElectionCompound @@ -17,9 +19,9 @@ def get_election_summary( election: Election | ArchivedResult, - request: 'ElectionDayRequest | None', + request: ElectionDayRequest | None, url: str | None = None -) -> 'JSONObject_ro': +) -> JSONObject_ro: """ Returns some basic informations about the given election as a JSON seriazable dict. """ @@ -43,11 +45,11 @@ def get_election_summary( def get_election_compound_summary( - election_compound: 'ElectionCompoundOrPart | ArchivedResult', - request: 'ElectionDayRequest | None', + election_compound: ElectionCompoundOrPart | ArchivedResult, + request: ElectionDayRequest | None, url: str | None = None, type_: str = 'election_compound' -) -> 'JSONObject_ro': +) -> JSONObject_ro: last_modified = election_compound.last_modified @@ -75,9 +77,9 @@ def get_election_compound_summary( def get_vote_summary( vote: Vote | ArchivedResult, - request: 'ElectionDayRequest | None', + request: ElectionDayRequest | None, url: str | None = None -) -> 'JSONObject_ro': +) -> JSONObject_ro: """ Returns some basic informations about the given vote as a JSON seriazable dict. """ @@ -119,8 +121,8 @@ def get_vote_summary( def get_summary( item: Election | ElectionCompound | Vote | ArchivedResult, - request: 'ElectionDayRequest' -) -> 'JSONObject_ro': + request: ElectionDayRequest +) -> JSONObject_ro: """ Returns some basic informations about the given election/vote as a JSON seriazable dict. """ @@ -153,9 +155,9 @@ def get_summary( def get_summaries( - items: 'Iterable[Election | ElectionCompound | Vote | ArchivedResult]', - request: 'ElectionDayRequest' -) -> list['JSONObject_ro']: + items: Iterable[Election | ElectionCompound | Vote | ArchivedResult], + request: ElectionDayRequest +) -> list[JSONObject_ro]: """ Converts the given list of election/votes to a JSON seriazable list of summaries. diff --git a/src/onegov/election_day/utils/svg_generator.py b/src/onegov/election_day/utils/svg_generator.py index b8d8bdff43..2ac19c1941 100644 --- a/src/onegov/election_day/utils/svg_generator.py +++ b/src/onegov/election_day/utils/svg_generator.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os.path from onegov.election_day import log from onegov.election_day.models import Ballot @@ -19,7 +21,7 @@ class SvgGenerator: def __init__( self, - app: 'ElectionDayApp', + app: ElectionDayApp, renderer: D3Renderer | None = None ): self.app = app @@ -27,7 +29,7 @@ def __init__( self.session = self.app.session() self.renderer = renderer or D3Renderer(app) - def remove(self, directory: str, files: 'Collection[str]') -> None: + def remove(self, directory: str, files: Collection[str]) -> None: """ Safely removes the given files from the directory. """ if not files: return diff --git a/src/onegov/election_day/utils/vote/__init__.py b/src/onegov/election_day/utils/vote/__init__.py index 4c97b2dc68..dc8c2b7635 100644 --- a/src/onegov/election_day/utils/vote/__init__.py +++ b/src/onegov/election_day/utils/vote/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day.utils.vote.ballot import get_ballot_data_by_district from onegov.election_day.utils.vote.ballot import get_ballot_data_by_entity diff --git a/src/onegov/election_day/utils/vote/ballot.py b/src/onegov/election_day/utils/vote/ballot.py index 902fbe17a6..674a39ff48 100644 --- a/src/onegov/election_day/utils/vote/ballot.py +++ b/src/onegov/election_day/utils/vote/ballot.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import TYPE_CHECKING if TYPE_CHECKING: from onegov.election_day.models import Ballot @@ -12,7 +14,7 @@ class DistrictData(EntityData): entities: list[int] -def get_ballot_data_by_entity(ballot: 'Ballot') -> dict[int, 'EntityData']: +def get_ballot_data_by_entity(ballot: Ballot) -> dict[int, EntityData]: """ Returns the yeas/nays percentage by entity_id. """ data = {} @@ -25,7 +27,7 @@ def get_ballot_data_by_entity(ballot: 'Ballot') -> dict[int, 'EntityData']: return data -def get_ballot_data_by_district(ballot: 'Ballot') -> dict[str, 'DistrictData']: +def get_ballot_data_by_district(ballot: Ballot) -> dict[str, DistrictData]: """ Returns the yeas/nays percentage grouped and keyed by district. """ data = {} diff --git a/src/onegov/election_day/views/archive.py b/src/onegov/election_day/views/archive.py index 6456ffef66..3554a219e4 100644 --- a/src/onegov/election_day/views/archive.py +++ b/src/onegov/election_day/views/archive.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from fs.errors import ResourceNotFound from morepath.request import Response from onegov.election_day import ElectionDayApp @@ -29,8 +31,8 @@ ) def view_archive( self: ArchivedResultCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Shows all the results from the elections and votes for a given year or date. @@ -53,8 +55,8 @@ def view_archive( ) def view_archive_json( self: ArchivedResultCollection, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ Shows all the results from the elections and votes for a given year or date as JSON. @@ -85,8 +87,8 @@ def add_headers(response: Response) -> None: ) def view_principal( self: Principal, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Shows all the results from the elections and votes of the last election day. It's the landing page. @@ -110,8 +112,8 @@ def view_principal( ) def view_principal_json( self: Principal, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ Shows all the results from the elections and votes of the last election day as JSON. @@ -138,7 +140,7 @@ def add_headers(response: Response) -> None: def search_form( model: SearchableArchivedResultCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: None = None ) -> type[ArchiveSearchFormVote | ArchiveSearchFormElection]: @@ -155,9 +157,9 @@ def search_form( ) def view_archive_search( self: SearchableArchivedResultCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: ArchiveSearchFormVote | ArchiveSearchFormElection -) -> 'RenderData': +) -> RenderData: """ Shows all the results from the elections and votes of the last election day. It's the landing page. """ @@ -186,7 +188,7 @@ def view_archive_search( ) def view_archive_download( self: Principal, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> Response: filestorage = request.app.filestorage diff --git a/src/onegov/election_day/views/auth.py b/src/onegov/election_day/views/auth.py index a3df85bea6..3037b90398 100644 --- a/src/onegov/election_day/views/auth.py +++ b/src/onegov/election_day/views/auth.py @@ -1,4 +1,6 @@ """ The authentication views. """ +from __future__ import annotations + from morepath import redirect from onegov.core.security import Private from onegov.core.security import Public @@ -36,9 +38,9 @@ ) def handle_login( self: Auth, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: LoginForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Handles the login requests. """ if form.submitted(request): @@ -62,7 +64,7 @@ def handle_login( name='logout', permission=Private ) -def view_logout(self: Auth, request: 'ElectionDayRequest') -> 'Response': +def view_logout(self: Auth, request: ElectionDayRequest) -> Response: """ Handles the logout requests. """ @@ -78,9 +80,9 @@ def view_logout(self: Auth, request: 'ElectionDayRequest') -> 'Response': ) def handle_password_reset_request( self: Principal, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: PasswordResetForm -) -> 'RenderData': +) -> RenderData: """ Handles the password reset requests. """ show_form = True @@ -150,9 +152,9 @@ def handle_password_reset_request( ) def handle_password_reset( self: Principal, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: PasswordResetForm -) -> 'RenderData': +) -> RenderData: """ Handles password reset requests. """ callout = None @@ -193,15 +195,15 @@ def handle_password_reset( ) def handle_totp_second_factor( self: Auth, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: TOTPForm -) -> 'RenderData | Response': +) -> RenderData | Response: if not request.app.totp_enabled: raise exc.HTTPNotFound() @request.after - def respond_with_no_index(response: 'Response') -> None: + def respond_with_no_index(response: Response) -> None: response.headers['X-Robots-Tag'] = 'noindex' users = UserCollection(request.session) diff --git a/src/onegov/election_day/views/election/candidate_district.py b/src/onegov/election_day/views/election/candidate_district.py index 2460041e4f..55cc26a749 100644 --- a/src/onegov/election_day/views/election/candidate_district.py +++ b/src/onegov/election_day/views/election/candidate_district.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day import ElectionDayApp from onegov.election_day.hidden_by_principal import \ @@ -18,7 +20,7 @@ def candidate_options( - request: 'ElectionDayRequest', + request: ElectionDayRequest, election: Election ) -> list[tuple[str, str]]: @@ -58,8 +60,8 @@ def ordering_completed(candidate: Candidate) -> tuple[bool, str, str]: ) def view_candidate_by_district( self: Candidate, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the candidate by district as JSON. """ return self.percentage_by_district # type:ignore[return-value] @@ -73,8 +75,8 @@ def view_candidate_by_district( ) def view_election_candidate_by_district( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the candidate as heatmap by district. """ layout = ElectionLayout(self, request, 'candidate-by-district') @@ -114,12 +116,12 @@ def view_election_candidate_by_district( ) def view_election_candidate_by_district_chart( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Embed the heatmap. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) options = candidate_options(request, self) diff --git a/src/onegov/election_day/views/election/candidate_entity.py b/src/onegov/election_day/views/election/candidate_entity.py index c0192a433d..aff9730181 100644 --- a/src/onegov/election_day/views/election/candidate_entity.py +++ b/src/onegov/election_day/views/election/candidate_entity.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day import ElectionDayApp from onegov.election_day.hidden_by_principal import \ @@ -18,7 +20,7 @@ def candidate_options( - request: 'ElectionDayRequest', + request: ElectionDayRequest, election: Election ) -> list[tuple[str, str]]: @@ -57,8 +59,8 @@ def ordering_completed(candidate: Candidate) -> tuple[bool, str, str]: ) def view_candidate_by_entity( self: Candidate, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the candidate by entity as JSON. """ return self.percentage_by_entity # type:ignore[return-value] @@ -72,8 +74,8 @@ def view_candidate_by_entity( ) def view_election_candidate_by_entity( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the candidate as heatmap by entity. """ layout = ElectionLayout(self, request, 'candidate-by-entity') @@ -113,12 +115,12 @@ def view_election_candidate_by_entity( ) def view_election_candidate_by_entity_chart( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Embed the heatmap. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) options = candidate_options(request, self) diff --git a/src/onegov/election_day/views/election/candidates.py b/src/onegov/election_day/views/election/candidates.py index e5dacdaf84..ad09f9b58d 100644 --- a/src/onegov/election_day/views/election/candidates.py +++ b/src/onegov/election_day/views/election/candidates.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day import ElectionDayApp from onegov.election_day.hidden_by_principal import hide_candidates_chart @@ -33,8 +35,8 @@ ) def view_election_candidates_data( self: Election, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the candidates as JSON. Used to for the candidates bar chart. @@ -66,12 +68,12 @@ def view_election_candidates_data( ) def view_election_candidates_chart( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the candidates as bar chart. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) entity = request.params.get('entity', '') @@ -94,8 +96,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_candidates( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ entity = request.params.get('entity', '') @@ -128,12 +130,12 @@ def view_election_candidates( ) def view_election_lists_table( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the lists as table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) entity = request.params.get('entity', '') @@ -160,8 +162,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_candidates_svg( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the candidates as SVG. """ layout = ElectionLayout(self, request, 'candidates') diff --git a/src/onegov/election_day/views/election/connections.py b/src/onegov/election_day/views/election/connections.py index e7767f1627..def9c766a0 100644 --- a/src/onegov/election_day/views/election/connections.py +++ b/src/onegov/election_day/views/election/connections.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.hidden_by_principal import ( hide_connections_chart) @@ -32,8 +34,8 @@ ) def view_election_connections_data( self: Election, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the list connections as JSON. Used to for the connection sankey chart. @@ -50,12 +52,12 @@ def view_election_connections_data( ) def view_election_connections_chart( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the connections as sankey chart. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) skip_rendering = hide_connections_chart(self, request) @@ -77,12 +79,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_connections_table( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the connections tables as widget. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -102,8 +104,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_connections( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionLayout(self, request, 'connections') @@ -123,8 +125,8 @@ def view_election_connections( ) def view_election_connections_svg( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the connections as SVG. """ layout = ElectionLayout(self, request, 'connections') diff --git a/src/onegov/election_day/views/election/data.py b/src/onegov/election_day/views/election/data.py index b4021765eb..ab9058c018 100644 --- a/src/onegov/election_day/views/election/data.py +++ b/src/onegov/election_day/views/election/data.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import normalize_for_url from onegov.election_day import _ from onegov.election_day import ElectionDayApp @@ -29,8 +31,8 @@ ) def view_election_data( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionLayout(self, request, 'data') @@ -48,12 +50,12 @@ def view_election_data( ) def view_election_data_as_json( self: Election, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ View the raw data as JSON. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -69,12 +71,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_data_as_csv( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the raw data as CSV. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -90,8 +92,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_parties_data_as_json( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the raw parties data as JSON. """ @@ -101,7 +103,7 @@ def view_election_parties_data_as_json( self = cast('ProporzElection', self) @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) assert request.app.default_locale @@ -129,8 +131,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_parties_data_as_csv( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the raw parties data as CSV. """ @@ -140,7 +142,7 @@ def view_election_parties_data_as_csv( self = cast('ProporzElection', self) @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) assert request.app.default_locale @@ -167,8 +169,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_aggregated_connections_data( self: Election, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the list connections as JSON. """ diff --git a/src/onegov/election_day/views/election/list_district.py b/src/onegov/election_day/views/election/list_district.py index 8329d875c1..13d1c0b18a 100644 --- a/src/onegov/election_day/views/election/list_district.py +++ b/src/onegov/election_day/views/election/list_district.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionLayout @@ -18,7 +20,7 @@ def list_options( - request: 'ElectionDayRequest', + request: ElectionDayRequest, election: Election ) -> list[tuple[str, str]]: @@ -53,8 +55,8 @@ def ordering(list_: List) -> tuple[int, str]: ) def view_list_by_district( self: List, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the list by district as JSON. """ return self.percentage_by_district # type:ignore[return-value] @@ -68,8 +70,8 @@ def view_list_by_district( ) def view_election_list_by_district( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the list as heatmap by district. """ layout = ElectionLayout(self, request, 'list-by-district') @@ -108,12 +110,12 @@ def view_election_list_by_district( ) def view_election_list_by_district_chart( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Embed the heatmap. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) options = list_options(request, self) diff --git a/src/onegov/election_day/views/election/list_entity.py b/src/onegov/election_day/views/election/list_entity.py index 8f1f8c1bea..0c1801c793 100644 --- a/src/onegov/election_day/views/election/list_entity.py +++ b/src/onegov/election_day/views/election/list_entity.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionLayout @@ -18,7 +20,7 @@ def list_options( - request: 'ElectionDayRequest', + request: ElectionDayRequest, election: Election ) -> list[tuple[str, str]]: @@ -53,8 +55,8 @@ def ordering(list_: List) -> tuple[int, str]: ) def view_list_by_entity( self: List, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the list by entity as JSON. """ return self.percentage_by_entity # type:ignore[return-value] @@ -68,8 +70,8 @@ def view_list_by_entity( ) def view_election_list_by_entity( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the list as heatmap by entity. """ layout = ElectionLayout(self, request, 'list-by-entity') @@ -108,12 +110,12 @@ def view_election_list_by_entity( ) def view_election_list_by_entity_chart( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Embed the heatmap. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) options = list_options(request, self) diff --git a/src/onegov/election_day/views/election/lists.py b/src/onegov/election_day/views/election/lists.py index 06bfa326d7..eb50f6c773 100644 --- a/src/onegov/election_day/views/election/lists.py +++ b/src/onegov/election_day/views/election/lists.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionLayout from onegov.election_day.models import Election @@ -24,8 +26,8 @@ ) def view_election_lists_data( self: Election, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the lists as JSON. Used to for the lists bar chart. """ limit = get_parameter(request, 'limit', int, None) @@ -51,12 +53,12 @@ def view_election_lists_data( ) def view_election_lists_chart( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the lists as bar chart. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) entity = request.params.get('entity', '') @@ -78,12 +80,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_lists_table( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the lists as table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) entity = request.params.get('entity', '') @@ -107,8 +109,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_lists( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionLayout(self, request, 'lists') @@ -133,8 +135,8 @@ def view_election_lists( ) def view_election_lists_svg( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the lists as SVG. """ layout = ElectionLayout(self, request, 'lists') diff --git a/src/onegov/election_day/views/election/lists_panachage.py b/src/onegov/election_day/views/election/lists_panachage.py index ffbfb7bb4f..2126d2b3ec 100644 --- a/src/onegov/election_day/views/election/lists_panachage.py +++ b/src/onegov/election_day/views/election/lists_panachage.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionLayout from onegov.election_day.models import Election @@ -21,8 +23,8 @@ ) def view_election_lists_panachage_data( self: Election, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the panachage data as JSON. Used to for the panachage sankey chart. @@ -39,12 +41,12 @@ def view_election_lists_panachage_data( ) def view_election_lists_panachage_chart( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the panachage data as sankey chart. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -62,8 +64,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_lists_panachage( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionLayout(self, request, 'lists-panachage') @@ -81,8 +83,8 @@ def view_election_lists_panachage( ) def view_election_lists_panachage_svg( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the panachage as SVG. """ layout = ElectionLayout(self, request, 'lists-panachage') diff --git a/src/onegov/election_day/views/election/main.py b/src/onegov/election_day/views/election/main.py index a0bcbf38f8..d996525e78 100644 --- a/src/onegov/election_day/views/election/main.py +++ b/src/onegov/election_day/views/election/main.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import defaultdict from morepath import redirect from onegov.core.utils import normalize_for_url @@ -31,11 +33,11 @@ ) def view_election_head( self: Election, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, self.last_modified) @@ -46,8 +48,8 @@ def add_headers(response: 'Response') -> None: ) def view_election( self: Election, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """" The main view. """ @@ -61,15 +63,15 @@ def view_election( ) def view_election_json( self: Election, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" The main view as JSON. """ last_modified = self.last_modified assert last_modified is not None @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, last_modified) @@ -233,12 +235,12 @@ def add_headers(response: 'Response') -> None: ) def view_election_summary( self: Election, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ View the summary of the election as JSON. """ @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, self.last_modified) @@ -252,8 +254,8 @@ def add_headers(response: 'Response') -> None: ) def view_election_pdf( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the generated PDF. """ layout = ElectionLayout(self, request) diff --git a/src/onegov/election_day/views/election/parties_panachage.py b/src/onegov/election_day/views/election/parties_panachage.py index 1d69de6d0e..184b90701c 100644 --- a/src/onegov/election_day/views/election/parties_panachage.py +++ b/src/onegov/election_day/views/election/parties_panachage.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionLayout from onegov.election_day.models import Election @@ -21,8 +23,8 @@ ) def view_election_parties_panachage_data( self: Election, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the panachage data as JSON. Used to for the panachage sankey chart. @@ -39,12 +41,12 @@ def view_election_parties_panachage_data( ) def view_election_parties_panachage_chart( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the panachage data as sankey chart. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -62,8 +64,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_parties_panachage( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionLayout(self, request, 'parties-panachage') @@ -81,8 +83,8 @@ def view_election_parties_panachage( ) def view_election_parties_panachage_svg( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the panachage as SVG. """ layout = ElectionLayout(self, request, 'parties-panachage') diff --git a/src/onegov/election_day/views/election/party_strengths.py b/src/onegov/election_day/views/election/party_strengths.py index ccf91cae4c..fcd5c54524 100644 --- a/src/onegov/election_day/views/election/party_strengths.py +++ b/src/onegov/election_day/views/election/party_strengths.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionLayout from onegov.election_day.models import Election @@ -24,8 +26,8 @@ ) def view_election_party_strengths_data( self: Election, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ Retuns the data used for the grouped bar diagram showing the party results. @@ -43,13 +45,13 @@ def view_election_party_strengths_data( ) def view_election_party_strengths_chart( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the party strengths as grouped bar chart. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -68,13 +70,13 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_party_strengths_table( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the party strengths as table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) party_years, parties = get_party_results(self) @@ -102,8 +104,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_party_strengths( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionLayout(self, request, 'party-strengths') @@ -129,8 +131,8 @@ def view_election_party_strengths( ) def view_election_party_strengths_svg( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the party strengths as SVG. """ diff --git a/src/onegov/election_day/views/election/statistics.py b/src/onegov/election_day/views/election/statistics.py index cad8ead901..22d8c5aac4 100644 --- a/src/onegov/election_day/views/election/statistics.py +++ b/src/onegov/election_day/views/election/statistics.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionLayout from onegov.election_day.models import Election @@ -20,8 +22,8 @@ ) def view_election_statistics( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ return { @@ -38,12 +40,12 @@ def view_election_statistics( ) def view_election_statistics_table( self: Election, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View for the standalone statistics table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { diff --git a/src/onegov/election_day/views/election_compound/candidates.py b/src/onegov/election_day/views/election_compound/candidates.py index e9ae3da201..f4c668be49 100644 --- a/src/onegov/election_day/views/election_compound/candidates.py +++ b/src/onegov/election_day/views/election_compound/candidates.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundLayout from onegov.election_day.models import ElectionCompound @@ -36,8 +38,8 @@ def get_districts( ) def view_election_compound_candidates( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ session = request.app.session() @@ -59,12 +61,12 @@ def view_election_compound_candidates( ) def view_election_statistics_table( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View for the standalone statistics table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) session = request.app.session() diff --git a/src/onegov/election_day/views/election_compound/data.py b/src/onegov/election_day/views/election_compound/data.py index 86600557d9..45404cefde 100644 --- a/src/onegov/election_day/views/election_compound/data.py +++ b/src/onegov/election_day/views/election_compound/data.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import normalize_for_url from onegov.election_day import _ from onegov.election_day import ElectionDayApp @@ -25,8 +27,8 @@ ) def view_election_compound_data( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionCompoundLayout(self, request, 'data') @@ -44,12 +46,12 @@ def view_election_compound_data( ) def view_election_compound_data_as_json( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ View the raw data as JSON. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -67,12 +69,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_data_as_csv( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the raw data as CSV. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -90,12 +92,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_parties_data_as_json( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ View the raw parties data as JSON. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) assert request.app.default_locale @@ -121,12 +123,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_parties_data_as_csv( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the raw parties data as CSV. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) assert request.app.default_locale diff --git a/src/onegov/election_day/views/election_compound/districts.py b/src/onegov/election_day/views/election_compound/districts.py index a0dc1b9e95..93b4158bae 100644 --- a/src/onegov/election_day/views/election_compound/districts.py +++ b/src/onegov/election_day/views/election_compound/districts.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundLayout from onegov.election_day.models import ElectionCompound @@ -22,8 +24,8 @@ ) def view_election_compound_districts( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The districts view. """ return { @@ -39,8 +41,8 @@ def view_election_compound_districts( ) def view_election_compound_by_district( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the districts/regions/municipalities as JSON for the map. """ return get_districts_data(self, request.app.principal, request) @@ -54,12 +56,12 @@ def view_election_compound_by_district( ) def view_election_list_by_district_chart( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Embed the heatmap. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) scope = 'districts' @@ -90,12 +92,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_districts_table( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Displays the districts as standalone table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { diff --git a/src/onegov/election_day/views/election_compound/list_groups.py b/src/onegov/election_day/views/election_compound/list_groups.py index f2a4824194..6eef6d2019 100644 --- a/src/onegov/election_day/views/election_compound/list_groups.py +++ b/src/onegov/election_day/views/election_compound/list_groups.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundLayout from onegov.election_day.models import ElectionCompound @@ -22,8 +24,8 @@ ) def view_election_compound_list_groups_data( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the list groups as JSON. Used to for the lists bar chart. """ return get_list_groups_data(self) @@ -37,12 +39,12 @@ def view_election_compound_list_groups_data( ) def view_election_compound_list_groups_chart( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the list groups as bar chart. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -60,12 +62,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_list_groups_table( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the list groups as table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -85,8 +87,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_list_groups( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionCompoundLayout(self, request, 'list-groups') @@ -105,8 +107,8 @@ def view_election_compound_list_groups( ) def view_election_compound_list_groups_svg( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the list groups as SVG. """ layout = ElectionCompoundLayout(self, request, 'list-groups') diff --git a/src/onegov/election_day/views/election_compound/main.py b/src/onegov/election_day/views/election_compound/main.py index 07e76c3b75..57ce9cb1e8 100644 --- a/src/onegov/election_day/views/election_compound/main.py +++ b/src/onegov/election_day/views/election_compound/main.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import defaultdict from morepath import redirect from onegov.core.utils import normalize_for_url @@ -31,11 +33,11 @@ ) def view_election_compound_head( self: ElectionCompound, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, self.last_modified) @@ -46,8 +48,8 @@ def add_headers(response: 'Response') -> None: ) def view_election_compound( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """" The main view. """ return redirect(ElectionCompoundLayout(self, request).main_view) @@ -60,15 +62,15 @@ def view_election_compound( ) def view_election_compound_json( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" The main view as JSON. """ last_modified = self.last_modified assert last_modified is not None @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, last_modified) @@ -179,12 +181,12 @@ def add_headers(response: 'Response') -> None: ) def view_election_compound_summary( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ View the summary of the election compound as JSON. """ @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, self.last_modified) @@ -198,8 +200,8 @@ def add_headers(response: 'Response') -> None: ) def view_election_compound_pdf( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the generated PDF. """ layout = ElectionCompoundLayout(self, request) diff --git a/src/onegov/election_day/views/election_compound/parties_panachage.py b/src/onegov/election_day/views/election_compound/parties_panachage.py index 9d038c643c..d1eb8ea663 100644 --- a/src/onegov/election_day/views/election_compound/parties_panachage.py +++ b/src/onegov/election_day/views/election_compound/parties_panachage.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundLayout from onegov.election_day.models import ElectionCompound @@ -21,8 +23,8 @@ ) def view_election_compound_parties_panachage_data( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the panachage data as JSON. Used to for the panachage sankey chart. @@ -39,12 +41,12 @@ def view_election_compound_parties_panachage_data( ) def view_election_compound_parties_panachage_chart( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the panachage data as sankey chart. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -62,8 +64,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_parties_panachage( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionCompoundLayout(self, request, 'parties-panachage') @@ -81,8 +83,8 @@ def view_election_compound_parties_panachage( ) def view_election_compound_parties_panachage_svg( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the panachage as SVG. """ layout = ElectionCompoundLayout(self, request, 'parties-panachage') diff --git a/src/onegov/election_day/views/election_compound/party_strengths.py b/src/onegov/election_day/views/election_compound/party_strengths.py index 01299fac9a..10d8a29ae3 100644 --- a/src/onegov/election_day/views/election_compound/party_strengths.py +++ b/src/onegov/election_day/views/election_compound/party_strengths.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundLayout from onegov.election_day.models import ElectionCompound @@ -24,8 +26,8 @@ ) def view_election_compound_party_strengths_data( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ Retuns the data used for the grouped bar diagram showing the party results. @@ -43,12 +45,12 @@ def view_election_compound_party_strengths_data( ) def view_election_compound_party_strengths_chart( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the party strengths as grouped bar chart. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -67,12 +69,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_party_strengths_table( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the party strengths as table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) party_years, parties = get_party_results(self) @@ -100,8 +102,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_party_strengths( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionCompoundLayout(self, request, 'party-strengths') @@ -127,8 +129,8 @@ def view_election_compound_party_strengths( ) def view_election_compound_party_strengths_svg( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the party strengths as SVG. """ layout = ElectionCompoundLayout(self, request, 'party-strengths') diff --git a/src/onegov/election_day/views/election_compound/seat_allocation.py b/src/onegov/election_day/views/election_compound/seat_allocation.py index 1f10d2cbd7..85695e79c7 100644 --- a/src/onegov/election_day/views/election_compound/seat_allocation.py +++ b/src/onegov/election_day/views/election_compound/seat_allocation.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundLayout from onegov.election_day.models import ElectionCompound @@ -23,8 +25,8 @@ ) def view_election_compound_seat_allocation_data( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ Retuns the data used for the grouped bar diagram showing the seat allocation. @@ -41,12 +43,12 @@ def view_election_compound_seat_allocation_data( ) def view_election_compound_seat_allocation_chart( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the seat allocation as grouped bar chart. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -64,8 +66,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_seat_allocation( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionCompoundLayout(self, request, 'seat-allocation') @@ -88,8 +90,8 @@ def view_election_compound_seat_allocation( ) def view_election_compound_seat_allocation_svg( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the seat allocation as SVG. """ layout = ElectionCompoundLayout(self, request, 'seat-allocation') @@ -107,12 +109,12 @@ def view_election_compound_seat_allocation_svg( ) def view_election_compound_seat_allocation_table( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Displays the seat allocation as standalone table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) party_years, parties = get_party_results(self) diff --git a/src/onegov/election_day/views/election_compound/statistics.py b/src/onegov/election_day/views/election_compound/statistics.py index 26fc32a60d..487fb61038 100644 --- a/src/onegov/election_day/views/election_compound/statistics.py +++ b/src/onegov/election_day/views/election_compound/statistics.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundLayout from onegov.election_day.models import ElectionCompound @@ -23,8 +25,8 @@ ) def view_election_statistics( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ elected_candidates = get_elected_candidates(self, request.session).all() @@ -45,12 +47,12 @@ def view_election_statistics( ) def view_election_statistics_table( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View for the standalone statistics table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { diff --git a/src/onegov/election_day/views/election_compound/superregions.py b/src/onegov/election_day/views/election_compound/superregions.py index 88cb2e5ed4..d84fd30a2c 100644 --- a/src/onegov/election_day/views/election_compound/superregions.py +++ b/src/onegov/election_day/views/election_compound/superregions.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundLayout from onegov.election_day.models import ElectionCompound @@ -23,8 +25,8 @@ ) def view_election_compound_superregions( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The superregions view. """ return { @@ -41,8 +43,8 @@ def view_election_compound_superregions( ) def view_election_compound_by_superregion( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the superregions/regions/municipalities as JSON for the map. """ return get_superregions_data(self, request.app.principal, request) @@ -56,12 +58,12 @@ def view_election_compound_by_superregion( ) def view_election_list_by_superregion_chart( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Embed the heatmap. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -88,12 +90,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_superregions_table( self: ElectionCompound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Displays the superregions as standalone table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { diff --git a/src/onegov/election_day/views/election_compound_part/candidates.py b/src/onegov/election_day/views/election_compound_part/candidates.py index 4622df6c24..378b5561fe 100644 --- a/src/onegov/election_day/views/election_compound_part/candidates.py +++ b/src/onegov/election_day/views/election_compound_part/candidates.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundPartLayout from onegov.election_day.models import ElectionCompoundPart @@ -36,8 +38,8 @@ def get_districts( ) def view_election_compound_part_candidates( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ session = request.app.session() @@ -59,12 +61,12 @@ def view_election_compound_part_candidates( ) def view_election_compound_part_statistics_table( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View for the standalone statistics table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) session = request.app.session() diff --git a/src/onegov/election_day/views/election_compound_part/districts.py b/src/onegov/election_day/views/election_compound_part/districts.py index db1bfca68e..293646e33b 100644 --- a/src/onegov/election_day/views/election_compound_part/districts.py +++ b/src/onegov/election_day/views/election_compound_part/districts.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundPartLayout from onegov.election_day.models import ElectionCompoundPart @@ -22,8 +24,8 @@ ) def view_election_compound_part_districts( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The districts view. """ @@ -47,8 +49,8 @@ def view_election_compound_part_districts( ) def view_election_compound_part_by_district( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" View the districts/regions/municipalities as JSON for the map. """ return get_districts_data(self, request.app.principal, request) @@ -62,13 +64,13 @@ def view_election_compound_part_by_district( ) def view_election_list_by_district_chart( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Embed the heatmap. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) scope = 'districts' @@ -99,13 +101,13 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_part_districts_table( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Displays the districts as standalone table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { diff --git a/src/onegov/election_day/views/election_compound_part/main.py b/src/onegov/election_day/views/election_compound_part/main.py index 43fe1b5b5a..46e88ce186 100644 --- a/src/onegov/election_day/views/election_compound_part/main.py +++ b/src/onegov/election_day/views/election_compound_part/main.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundPartLayout @@ -28,11 +30,11 @@ ) def view_election_compound_part_head( self: ElectionCompoundPart, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, self.last_modified) @@ -43,8 +45,8 @@ def add_headers(response: 'Response') -> None: ) def view_election_compound_part( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """" The main view. """ return redirect(ElectionCompoundPartLayout(self, request).main_view) @@ -57,15 +59,15 @@ def view_election_compound_part( ) def view_election_compound_part_json( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """" The main view as JSON. """ last_modified = self.last_modified assert last_modified is not None @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, last_modified) @@ -146,12 +148,12 @@ def add_headers(response: 'Response') -> None: ) def view_election_compound_part_summary( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ View the summary of the election compound part as JSON. """ @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, self.last_modified) diff --git a/src/onegov/election_day/views/election_compound_part/party_strengths.py b/src/onegov/election_day/views/election_compound_part/party_strengths.py index d6457e32d4..4b84d332a0 100644 --- a/src/onegov/election_day/views/election_compound_part/party_strengths.py +++ b/src/onegov/election_day/views/election_compound_part/party_strengths.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundPartLayout from onegov.election_day.models import ElectionCompoundPart @@ -24,8 +26,8 @@ ) def view_election_compound_part_party_strengths_data( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ Retuns the data used for the grouped bar diagram showing the party results. @@ -43,12 +45,12 @@ def view_election_compound_part_party_strengths_data( ) def view_election_compound_part_party_strengths_chart( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the party strengths as grouped bar chart. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -67,12 +69,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_party_strengths_table( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the party strengths as table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) party_years, parties = get_party_results(self) @@ -100,8 +102,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_election_compound_part_party_strengths( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = ElectionCompoundPartLayout(self, request, 'party-strengths') @@ -127,8 +129,8 @@ def view_election_compound_part_party_strengths( ) def view_election_compound_part_party_strengths_svg( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the party strengths as SVG. """ layout = ElectionCompoundPartLayout(self, request, 'party-strengths') diff --git a/src/onegov/election_day/views/election_compound_part/statistics.py b/src/onegov/election_day/views/election_compound_part/statistics.py index 5b459f89cb..6aed589b3f 100644 --- a/src/onegov/election_day/views/election_compound_part/statistics.py +++ b/src/onegov/election_day/views/election_compound_part/statistics.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import ElectionCompoundPartLayout from onegov.election_day.models import ElectionCompoundPart @@ -23,8 +25,8 @@ ) def view_election_compound_part_statistics( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ elected_candidates = get_elected_candidates(self, request.session).all() @@ -45,12 +47,12 @@ def view_election_compound_part_statistics( ) def view_election_compound_part_statistics_table( self: ElectionCompoundPart, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View for the standalone statistics table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { diff --git a/src/onegov/election_day/views/exceptionviews.py b/src/onegov/election_day/views/exceptionviews.py index 4e228ad164..fe4c908db9 100644 --- a/src/onegov/election_day/views/exceptionviews.py +++ b/src/onegov/election_day/views/exceptionviews.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Public from onegov.election_day import _ from onegov.election_day import ElectionDayApp @@ -21,13 +23,13 @@ ) def handle_forbidden( self: HTTPForbidden, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Displays a nice HTTP 403 error. """ @request.after - def set_status_code(response: 'Response') -> None: + def set_status_code(response: Response) -> None: response.status_code = self.code # pass along 403 return { @@ -46,13 +48,13 @@ def set_status_code(response: 'Response') -> None: ) def handle_notfound( self: HTTPNotFound, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Displays a nice HTTP 404 error. """ @request.after - def set_status_code(response: 'Response') -> None: + def set_status_code(response: Response) -> None: response.status_code = self.code # pass along 404 return { @@ -69,13 +71,13 @@ def set_status_code(response: 'Response') -> None: ) def handle_accepted( self: HTTPAccepted, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Displays a nice HTTP 202 exception. """ @request.after - def set_status_code(response: 'Response') -> None: + def set_status_code(response: Response) -> None: response.status_code = self.code return { diff --git a/src/onegov/election_day/views/locale.py b/src/onegov/election_day/views/locale.py index ea070ba477..1c9027de59 100644 --- a/src/onegov/election_day/views/locale.py +++ b/src/onegov/election_day/views/locale.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.i18n import SiteLocale from onegov.core.security import Public from onegov.election_day import ElectionDayApp @@ -15,8 +17,8 @@ ) def change_site_locale( self: SiteLocale, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ Changes the locale. """ return self.redirect(request) diff --git a/src/onegov/election_day/views/manage/archive.py b/src/onegov/election_day/views/manage/archive.py index d8fafcf1f6..d8843636f5 100644 --- a/src/onegov/election_day/views/manage/archive.py +++ b/src/onegov/election_day/views/manage/archive.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.security import Secret from onegov.election_day import _ @@ -24,9 +26,9 @@ ) def view_update_results( self: Principal, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: EmptyForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Updates all archived results. """ layout = DefaultLayout(self, request) diff --git a/src/onegov/election_day/views/manage/cache.py b/src/onegov/election_day/views/manage/cache.py index f5dcb49081..6443c51bb2 100644 --- a/src/onegov/election_day/views/manage/cache.py +++ b/src/onegov/election_day/views/manage/cache.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.security import Secret from onegov.election_day import _ @@ -23,9 +25,9 @@ ) def view_clear_pages_cache( self: Principal, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: EmptyForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Clears the pages cache. """ layout = DefaultLayout(self, request) diff --git a/src/onegov/election_day/views/manage/data_sources.py b/src/onegov/election_day/views/manage/data_sources.py index ae0d903ad7..641052e8d5 100644 --- a/src/onegov/election_day/views/manage/data_sources.py +++ b/src/onegov/election_day/views/manage/data_sources.py @@ -1,4 +1,5 @@ """ The manage subscription views. """ +from __future__ import annotations import morepath @@ -30,8 +31,8 @@ ) def view_data_sources( self: DataSourceCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View all data sources as a list. """ return { @@ -50,9 +51,9 @@ def view_data_sources( ) def create_data_source( self: DataSourceCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: DataSourceForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Create a new data source. """ layout = ManageDataSourcesLayout(self, request) @@ -79,8 +80,8 @@ def create_data_source( ) def manage_data_source( self: DataSource, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ Manage the data source. Redirect to the list of data source items. @@ -97,9 +98,9 @@ def manage_data_source( ) def generate_data_source_token( self: DataSource, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Regenerate a new token for the data source. """ layout = ManageDataSourcesLayout(self, request) @@ -127,9 +128,9 @@ def generate_data_source_token( ) def delete_data_source( self: DataSource, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Delete the data source item. """ layout = ManageDataSourcesLayout(self, request) @@ -163,8 +164,8 @@ def delete_data_source( ) def view_data_source_items( self: DataSourceItemCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View all data source items as a list. """ assert self.source is not None @@ -185,9 +186,9 @@ def view_data_source_items( ) def create_data_source_item( self: DataSourceItemCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: DataSourceItemForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Create a new data source item. """ layout = ManageDataSourceItemsLayout(self, request) @@ -218,9 +219,9 @@ def create_data_source_item( ) def edit_data_source_item( self: DataSourceItem, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: DataSourceItemForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Edit a data source item. """ layout = ManageDataSourceItemsLayout(self.source, request) @@ -250,9 +251,9 @@ def edit_data_source_item( ) def delete_data_source_item( self: DataSourceItem, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Delete the data source item. """ layout = ManageDataSourceItemsLayout(self.source, request) diff --git a/src/onegov/election_day/views/manage/election_compounds.py b/src/onegov/election_day/views/manage/election_compounds.py index ae99a03938..a9e3fb9575 100644 --- a/src/onegov/election_day/views/manage/election_compounds.py +++ b/src/onegov/election_day/views/manage/election_compounds.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.utils import groupbylist from onegov.election_day import _ @@ -27,8 +29,8 @@ ) def view_election_compounds( self: ElectionCompoundCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View a list of all election compoundss. """ years = [ @@ -56,9 +58,9 @@ def view_election_compounds( ) def create_election_compound( self: ElectionCompoundCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: ElectionCompoundForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Create a new election compound. """ layout = ManageElectionCompoundsLayout(self, request) @@ -89,9 +91,9 @@ def create_election_compound( ) def edit_election_compound( self: ElectionCompound, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: ElectionCompoundForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Edit an existing election compound. """ layout = ManageElectionCompoundsLayout(self, request) @@ -125,9 +127,9 @@ def edit_election_compound( ) def clear_election_compound( self: ElectionCompound, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: ClearResultsForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Clear the results of an election ompound. """ layout = ManageElectionCompoundsLayout(self, request) @@ -163,9 +165,9 @@ def clear_election_compound( ) def clear_election_compound_media( self: ElectionCompound, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Deletes alls SVGs and PDFs of this election compound. """ layout = ManageElectionCompoundsLayout(self, request) @@ -208,9 +210,9 @@ def clear_election_compound_media( ) def delete_election_compound( self: ElectionCompound, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Delete an existing election compound. """ layout = ManageElectionCompoundsLayout(self, request) @@ -248,9 +250,9 @@ def delete_election_compound( ) def trigger_election( self: ElectionCompound, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: TriggerNotificationForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Trigger the notifications related to an election. """ session = request.session diff --git a/src/onegov/election_day/views/manage/elections.py b/src/onegov/election_day/views/manage/elections.py index 257904cd28..dcef7589c2 100644 --- a/src/onegov/election_day/views/manage/elections.py +++ b/src/onegov/election_day/views/manage/elections.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.utils import groupbylist from onegov.election_day import _ @@ -27,8 +29,8 @@ ) def view_elections( self: ElectionCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View a list of all elections. """ years = [ @@ -56,9 +58,9 @@ def view_elections( ) def create_election( self: ElectionCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: ElectionForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Create a new election. """ layout = ManageElectionsLayout(self, request) @@ -89,9 +91,9 @@ def create_election( ) def edit_election( self: Election, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: ElectionForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Edit an existing election. """ layout = ManageElectionsLayout(self, request) @@ -125,9 +127,9 @@ def edit_election( ) def clear_election( self: Election, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: ClearResultsForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Clear the results of an election. """ layout = ManageElectionsLayout(self, request) @@ -163,9 +165,9 @@ def clear_election( ) def clear_election_media( self: Election, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Deletes alls SVGs and PDFs of this election. """ layout = ManageElectionsLayout(self, request) @@ -208,9 +210,9 @@ def clear_election_media( ) def delete_election( self: Election, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Delete an existing election. """ layout = ManageElectionsLayout(self, request) @@ -248,9 +250,9 @@ def delete_election( ) def trigger_election( self: Election, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: TriggerNotificationForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Trigger the notifications related to an election. """ session = request.session diff --git a/src/onegov/election_day/views/manage/notifications.py b/src/onegov/election_day/views/manage/notifications.py index 09e24b48f4..547b96e377 100644 --- a/src/onegov/election_day/views/manage/notifications.py +++ b/src/onegov/election_day/views/manage/notifications.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.election_day import _ from onegov.election_day import ElectionDayApp @@ -25,9 +27,9 @@ ) def view_trigger_notficiations( self: Principal, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: TriggerNotificationsForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Trigger the notifications of the current election day. """ diff --git a/src/onegov/election_day/views/manage/screens.py b/src/onegov/election_day/views/manage/screens.py index d40a6f07e4..2de090d56f 100644 --- a/src/onegov/election_day/views/manage/screens.py +++ b/src/onegov/election_day/views/manage/screens.py @@ -1,4 +1,5 @@ """ The manage screen views. """ +from __future__ import annotations from morepath import redirect from onegov.core.security import Private @@ -24,8 +25,8 @@ ) def view_screens( self: ScreenCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View all screens as a list. """ return { @@ -44,8 +45,8 @@ def view_screens( ) def export_screens( self: ScreenCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Export all screens as a CSV file. """ return { @@ -61,9 +62,9 @@ def export_screens( ) def create_screen( self: ScreenCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: ScreenForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Create a new screen. """ layout = ManageScreensLayout(self, request) @@ -91,9 +92,9 @@ def create_screen( ) def edit_screen_item( self: Screen, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: ScreenForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Edit a screen. """ layout = ManageScreensLayout(self, request) @@ -125,9 +126,9 @@ def edit_screen_item( ) def delete_screen( self: Screen, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Delete a screen. """ layout = ManageScreensLayout(self, request) diff --git a/src/onegov/election_day/views/manage/subscribers.py b/src/onegov/election_day/views/manage/subscribers.py index 0b14328d64..9290de9c1e 100644 --- a/src/onegov/election_day/views/manage/subscribers.py +++ b/src/onegov/election_day/views/manage/subscribers.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.security import Private from onegov.election_day import _ @@ -24,8 +26,8 @@ ) def view_sms_subscribers( self: SmsSubscriberCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View a list with all SMS subscribers. """ return { @@ -44,8 +46,8 @@ def view_sms_subscribers( ) def view_email_subscribers( self: EmailSubscriberCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View a list with all email subscribers. """ return { @@ -65,8 +67,8 @@ def view_email_subscribers( ) def export_sms_subscribers( self: SmsSubscriberCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Export all SMS subscribers as a CSV. """ @@ -83,8 +85,8 @@ def export_sms_subscribers( ) def export_email_subscribers( self: EmailSubscriberCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Export all email subscribers as a CSV. """ @@ -96,9 +98,9 @@ def export_email_subscribers( def handle_cleanup_subscribers( collection: EmailSubscriberCollection | SmsSubscriberCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: SubscribersCleanupForm -) -> 'RenderData | Response': +) -> RenderData | Response: layout = ManageSubscribersLayout(collection, request) @@ -137,9 +139,9 @@ def handle_cleanup_subscribers( ) def cleanup_sms_subscribers( self: SmsSubscriberCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: SubscribersCleanupForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Deletes a list of SMS subscribers. """ @@ -153,9 +155,9 @@ def cleanup_sms_subscribers( ) def cleanup_email_subscribers( self: EmailSubscriberCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: SubscribersCleanupForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Deletes a list of email subscribers. """ @@ -168,9 +170,9 @@ def cleanup_email_subscribers( ) def delete_subscriber( self: Subscriber, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Delete a single subscriber. """ @@ -204,9 +206,9 @@ def delete_subscriber( ) def activate_subscriber( self: Subscriber, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Activate a single subscriber. """ @@ -240,9 +242,9 @@ def activate_subscriber( ) def deactivate_subscriber( self: Subscriber, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Deactivate a single subscriber. """ diff --git a/src/onegov/election_day/views/manage/upload_tokens.py b/src/onegov/election_day/views/manage/upload_tokens.py index a780652608..79592c2753 100644 --- a/src/onegov/election_day/views/manage/upload_tokens.py +++ b/src/onegov/election_day/views/manage/upload_tokens.py @@ -1,4 +1,5 @@ """ The manage subscription views. """ +from __future__ import annotations import morepath @@ -23,8 +24,8 @@ ) def view_upload_tokens( self: UploadTokenCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View all upload tokens as a list. """ return { @@ -42,9 +43,9 @@ def view_upload_tokens( ) def create_upload_token( self: UploadTokenCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: EmptyForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Create a new upload token. """ layout = ManageUploadTokensLayout(self, request) @@ -70,9 +71,9 @@ def create_upload_token( ) def delete_upload_token( self: UploadToken, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: EmptyForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Delete the upload token item. """ layout = ManageUploadTokensLayout(self, request) diff --git a/src/onegov/election_day/views/manage/votes.py b/src/onegov/election_day/views/manage/votes.py index 79f3ba0939..09387d6028 100644 --- a/src/onegov/election_day/views/manage/votes.py +++ b/src/onegov/election_day/views/manage/votes.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.utils import groupbylist from onegov.election_day import _ @@ -27,8 +29,8 @@ ) def view_votes( self: VoteCollection, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View a list of all votes. """ years = [ @@ -56,9 +58,9 @@ def view_votes( ) def create_vote( self: VoteCollection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: VoteForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Create a new vote. """ layout = ManageVotesLayout(self, request) @@ -89,9 +91,9 @@ def create_vote( ) def edit_vote( self: Vote, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: VoteForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Edit an existing vote. """ layout = ManageVotesLayout(self, request) @@ -125,9 +127,9 @@ def edit_vote( ) def clear_vote( self: Vote, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: ClearResultsForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Clear the results of a vote. """ layout = ManageVotesLayout(self, request) @@ -163,9 +165,9 @@ def clear_vote( ) def clear_election_media( self: Vote, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Deletes alls SVGs and PDFs of this vote. """ layout = ManageVotesLayout(self, request) @@ -208,9 +210,9 @@ def clear_election_media( ) def delete_vote( self: Vote, - request: 'ElectionDayRequest', - form: 'EmptyForm' -) -> 'RenderData | Response': + request: ElectionDayRequest, + form: EmptyForm +) -> RenderData | Response: """ Delete an existing vote. """ layout = ManageVotesLayout(self, request) @@ -248,9 +250,9 @@ def delete_vote( ) def trigger_vote( self: Vote, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: TriggerNotificationForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Trigger the notifications related to a vote. """ session = request.session diff --git a/src/onegov/election_day/views/opendata_swiss.py b/src/onegov/election_day/views/opendata_swiss.py index a2fa259558..8ee4484e44 100644 --- a/src/onegov/election_day/views/opendata_swiss.py +++ b/src/onegov/election_day/views/opendata_swiss.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from babel.dates import format_date from io import BytesIO from onegov.core.security import Public @@ -40,7 +42,7 @@ def sub( name='catalog.rdf', permission=Public ) -def view_rdf(self: Principal, request: 'ElectionDayRequest') -> bytes: +def view_rdf(self: Principal, request: ElectionDayRequest) -> bytes: """ Returns an XML / RDF / DCAT-AP for Switzerland format for opendata.swiss. @@ -58,7 +60,7 @@ def view_rdf(self: Principal, request: 'ElectionDayRequest') -> bytes: raise HTTPNotImplemented() @request.after - def set_headers(response: 'Response') -> None: + def set_headers(response: Response) -> None: response.headers['Content-Type'] = 'application/rdf+xml; charset=UTF-8' layout = DefaultLayout(self, request) @@ -89,7 +91,7 @@ def set_headers(response: 'Response') -> None: translations = request.app.translations - def translate(text: 'TranslationString', locale: str) -> str: + def translate(text: TranslationString, locale: str) -> str: translator = translations.get(locale) if translator: return text.interpolate(translator.gettext(text)) diff --git a/src/onegov/election_day/views/screen.py b/src/onegov/election_day/views/screen.py index cda9856917..82b95b286a 100644 --- a/src/onegov/election_day/views/screen.py +++ b/src/onegov/election_day/views/screen.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.templates import PageTemplate from onegov.core.widgets import inject_variables from onegov.core.widgets import transform_structure @@ -25,11 +27,11 @@ template='screen.pt', permission=MaybePublic ) -def view_screen(self: Screen, request: 'ElectionDayRequest') -> 'RenderData': +def view_screen(self: Screen, request: ElectionDayRequest) -> RenderData: """ Shows a screen. """ @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, self.last_modified) @@ -71,11 +73,11 @@ def add_headers(response: 'Response') -> None: request_method='HEAD', permission=MaybePublic ) -def view_screen_head(self: Screen, request: 'ElectionDayRequest') -> None: +def view_screen_head(self: Screen, request: ElectionDayRequest) -> None: """ Get the last modification date. """ @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, self.last_modified) @@ -85,11 +87,11 @@ def add_headers(response: 'Response') -> None: name='json', permission=MaybePublic ) -def view_screen_json(self: Screen, request: 'ElectionDayRequest') -> 'JSON_ro': +def view_screen_json(self: Screen, request: ElectionDayRequest) -> JSON_ro: """ Get the last modification date. """ @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, self.last_modified) diff --git a/src/onegov/election_day/views/sitemap.py b/src/onegov/election_day/views/sitemap.py index daa8949c66..d970080519 100644 --- a/src/onegov/election_day/views/sitemap.py +++ b/src/onegov/election_day/views/sitemap.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import ElectionDayApp from onegov.election_day.collections import ArchivedResultCollection from onegov.election_day.layouts import DefaultLayout @@ -15,8 +17,8 @@ def urls( principal: Principal, - request: 'ElectionDayRequest' -) -> 'Iterator[str]': + request: ElectionDayRequest +) -> Iterator[str]: layout = DefaultLayout(principal, request) yield request.link(principal) @@ -49,8 +51,8 @@ def urls( ) def view_sitemap_xml( self: Principal, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Returns a XML-sitemap. See https://www.sitemaps.org for more information. @@ -58,7 +60,7 @@ def view_sitemap_xml( """ @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: response.headers['Content-Type'] = 'application/xml' return {'urls': sorted(urls(self, request))} @@ -71,8 +73,8 @@ def add_headers(response: 'Response') -> None: ) def view_sitemap_json( self: Principal, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Returns the XML-sitemap as json. """ return {'urls': sorted(urls(self, request))} @@ -86,8 +88,8 @@ def view_sitemap_json( ) def view_sitemap( self: Principal, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Returns a site map (with hiearchy). """ layout = DefaultLayout(self, request) diff --git a/src/onegov/election_day/views/subscription.py b/src/onegov/election_day/views/subscription.py index 6948f1e559..3231604362 100644 --- a/src/onegov/election_day/views/subscription.py +++ b/src/onegov/election_day/views/subscription.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath.request import Response from onegov.election_day import _ from onegov.election_day import ElectionDayApp @@ -26,9 +28,9 @@ ) def subscribe_email( self: Principal, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: EmailSubscriptionForm -) -> 'RenderData': +) -> RenderData: """ Initiate the email notification subscription. """ layout = DefaultLayout(self, request) @@ -71,9 +73,9 @@ def subscribe_email( ) def optin_email( self: Principal, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: EmailSubscriptionForm -) -> 'RenderData': +) -> RenderData: """ Confirm the email used for the subscription. """ callout = _('Subscription failed, the link is invalid.') @@ -119,9 +121,9 @@ def optin_email( ) def unsubscribe_email( self: Principal, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: EmailSubscriptionForm -) -> 'RenderData': +) -> RenderData: """ Initiates the email notification unsubscription. """ layout = DefaultLayout(self, request) @@ -158,9 +160,9 @@ def unsubscribe_email( ) def optout_email( self: Principal, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: EmailSubscriptionForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Deactivates the email subscription. Allows one-click unsubscription as defined by RFC-8058: @@ -212,9 +214,9 @@ def optout_email( ) def subscribe_sms( self: Principal, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: SmsSubscriptionForm -) -> 'RenderData': +) -> RenderData: """ Adds the given phone number to the SMS subscribers.""" layout = DefaultLayout(self, request) @@ -259,9 +261,9 @@ def subscribe_sms( ) def unsubscribe_sms( self: Principal, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: SmsSubscriptionForm -) -> 'RenderData': +) -> RenderData: """ Removes the given phone number from the SMS subscribers.""" layout = DefaultLayout(self, request) diff --git a/src/onegov/election_day/views/upload/__init__.py b/src/onegov/election_day/views/upload/__init__.py index e7a518f9b2..d6e3f0b822 100644 --- a/src/onegov/election_day/views/upload/__init__.py +++ b/src/onegov/election_day/views/upload/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.election_day import _ from onegov.election_day.formats.imports.common import FileImportError @@ -16,7 +18,7 @@ def unsupported_year_error(year: int) -> FileImportError: ) -def set_locale(request: 'ElectionDayRequest') -> None: +def set_locale(request: ElectionDayRequest) -> None: """ Sets the locale of the request by the Accept-Language header. """ locale = request.headers.get('Accept-Language') or 'en' @@ -26,7 +28,7 @@ def set_locale(request: 'ElectionDayRequest') -> None: def translate_errors( errors: dict[str, list[Any]], - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: """ Translates and interpolates the given error messages. """ diff --git a/src/onegov/election_day/views/upload/election.py b/src/onegov/election_day/views/upload/election.py index 257f17cc66..d731c5d71e 100644 --- a/src/onegov/election_day/views/upload/election.py +++ b/src/onegov/election_day/views/upload/election.py @@ -1,4 +1,6 @@ """ The upload view. """ +from __future__ import annotations + import morepath import transaction @@ -30,8 +32,8 @@ ) def view_upload_election( self: Election, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ Upload results of an election. Redirects to the majorz or proporz upload view. @@ -51,9 +53,9 @@ def view_upload_election( ) def view_upload_majorz_election( self: Election, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: UploadMajorzElectionForm -) -> 'RenderData': +) -> RenderData: """ Upload results of a majorz election. """ assert self.type == 'majorz' @@ -153,9 +155,9 @@ def view_upload_majorz_election( ) def view_upload_proporz_election( self: ProporzElection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: UploadProporzElectionForm -) -> 'RenderData': +) -> RenderData: """ Upload results of a proproz election. """ assert self.type == 'proporz' diff --git a/src/onegov/election_day/views/upload/election_compound.py b/src/onegov/election_day/views/upload/election_compound.py index b9ced91851..64a1069a1c 100644 --- a/src/onegov/election_day/views/upload/election_compound.py +++ b/src/onegov/election_day/views/upload/election_compound.py @@ -1,4 +1,6 @@ """ The upload view. """ +from __future__ import annotations + import transaction from onegov.election_day import ElectionDayApp @@ -24,9 +26,9 @@ ) def view_upload_election_compound( self: ElectionCompound, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: UploadElectionCompoundForm -) -> 'RenderData': +) -> RenderData: """ Upload results of a election compound. """ errors = [] diff --git a/src/onegov/election_day/views/upload/parties.py b/src/onegov/election_day/views/upload/parties.py index 40bdf6f04a..ccd066d913 100644 --- a/src/onegov/election_day/views/upload/parties.py +++ b/src/onegov/election_day/views/upload/parties.py @@ -1,4 +1,6 @@ """ The upload view. """ +from __future__ import annotations + import transaction from onegov.election_day import ElectionDayApp @@ -25,9 +27,9 @@ ) def view_upload_election_party_results( self: ProporzElection, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: UploadPartyResultsForm -) -> 'RenderData': +) -> RenderData: """ Uploads party results. """ errors = [] @@ -87,9 +89,9 @@ def view_upload_election_party_results( ) def view_upload_election_compound_party_results( self: ElectionCompound, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: UploadPartyResultsForm -) -> 'RenderData': +) -> RenderData: """ Uploads party results. """ errors = [] diff --git a/src/onegov/election_day/views/upload/rest.py b/src/onegov/election_day/views/upload/rest.py index 659d47443d..03dd3e159d 100644 --- a/src/onegov/election_day/views/upload/rest.py +++ b/src/onegov/election_day/views/upload/rest.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import transaction from base64 import b64decode @@ -37,7 +39,7 @@ from webob.response import Response -def authenticate(request: 'ElectionDayRequest') -> None: +def authenticate(request: ElectionDayRequest) -> None: try: token = b64decode( request.authorization[1] # type:ignore @@ -55,9 +57,9 @@ def authenticate(request: 'ElectionDayRequest') -> None: request_method='POST' ) def view_upload_rest( - self: 'Canton | Municipality', - request: 'ElectionDayRequest' -) -> 'RenderData': + self: Canton | Municipality, + request: ElectionDayRequest +) -> RenderData: """ Upload election or vote results via REST using the internal format. @@ -77,7 +79,7 @@ def view_upload_rest( status_code: int | None = None @request.after - def set_status_code(response: 'Response') -> None: + def set_status_code(response: Response) -> None: if status_code is not None: response.status_code = status_code diff --git a/src/onegov/election_day/views/upload/vote.py b/src/onegov/election_day/views/upload/vote.py index b4dfa357a8..d986ae5595 100644 --- a/src/onegov/election_day/views/upload/vote.py +++ b/src/onegov/election_day/views/upload/vote.py @@ -1,4 +1,6 @@ """ The upload view. """ +from __future__ import annotations + import transaction from onegov.election_day import ElectionDayApp @@ -26,9 +28,9 @@ ) def view_upload( self: Vote, - request: 'ElectionDayRequest', + request: ElectionDayRequest, form: UploadVoteForm -) -> 'RenderData': +) -> RenderData: """ Uploads votes results. """ errors = [] diff --git a/src/onegov/election_day/views/upload/wabsti_exporter.py b/src/onegov/election_day/views/upload/wabsti_exporter.py index ac366b99ad..9769de28e6 100644 --- a/src/onegov/election_day/views/upload/wabsti_exporter.py +++ b/src/onegov/election_day/views/upload/wabsti_exporter.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import transaction from base64 import b64decode @@ -31,7 +33,7 @@ from onegov.election_day.request import ElectionDayRequest -def authenticated_source(request: 'ElectionDayRequest') -> DataSource: +def authenticated_source(request: ElectionDayRequest) -> DataSource: try: token = b64decode( request.authorization[1] # type:ignore @@ -51,9 +53,9 @@ def authenticated_source(request: 'ElectionDayRequest') -> DataSource: permission=Public ) def view_upload_wabsti_vote( - self: 'Canton | Municipality', - request: 'ElectionDayRequest' -) -> 'RenderData': + self: Canton | Municipality, + request: ElectionDayRequest +) -> RenderData: """ Upload vote results using the WabstiCExportert 2.2+. @@ -150,9 +152,9 @@ def view_upload_wabsti_vote( permission=Public ) def view_upload_wabsti_majorz( - self: 'Canton | Municipality', - request: 'ElectionDayRequest' -) -> 'RenderData': + self: Canton | Municipality, + request: ElectionDayRequest +) -> RenderData: """ Upload election results using the WabstiCExportert 2.2+. Example usage: @@ -265,9 +267,9 @@ def view_upload_wabsti_majorz( permission=Public ) def view_upload_wabsti_proporz( - self: 'Canton | Municipality', - request: 'ElectionDayRequest' -) -> 'RenderData': + self: Canton | Municipality, + request: ElectionDayRequest +) -> RenderData: """ Upload election results using the WabstiCExportert 2.2+. Example usage: diff --git a/src/onegov/election_day/views/vote/data.py b/src/onegov/election_day/views/vote/data.py index 95f38225b6..6199991c90 100644 --- a/src/onegov/election_day/views/vote/data.py +++ b/src/onegov/election_day/views/vote/data.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import normalize_for_url from onegov.election_day import ElectionDayApp from onegov.election_day.formats import export_vote_internal @@ -23,8 +25,8 @@ ) def view_vote_data( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view. """ layout = VoteLayout(self, request, 'data') @@ -42,12 +44,12 @@ def view_vote_data( ) def view_vote_data_as_json( self: Vote, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ View the raw data as JSON. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { @@ -63,12 +65,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_vote_data_as_csv( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the raw data as CSV. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { diff --git a/src/onegov/election_day/views/vote/districts.py b/src/onegov/election_day/views/vote/districts.py index 07b293077f..adc69e6d5f 100644 --- a/src/onegov/election_day/views/vote/districts.py +++ b/src/onegov/election_day/views/vote/districts.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import VoteLayout @@ -25,8 +27,8 @@ ) def view_vote_districts( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view (proposal). """ layout = VoteLayout(self, request, 'districts') @@ -45,8 +47,8 @@ def view_vote_districts( ) def view_vote_districts_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view (proposal). """ layout = VoteLayout(self, request, 'proposal-districts') @@ -65,8 +67,8 @@ def view_vote_districts_proposal( ) def view_vote_districts_counter_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view (counter-proposal). """ layout = VoteLayout(self, request, 'counter-proposal-districts') @@ -85,8 +87,8 @@ def view_vote_districts_counter_proposal( ) def view_vote_districts_tie_breaker( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view (tie-breaker). """ layout = VoteLayout(self, request, 'tie-breaker-districts') @@ -104,8 +106,8 @@ def view_vote_districts_tie_breaker( ) def view_vote_districts_map_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the map of the proposal. """ ballot = getattr(self, 'proposal', None) @@ -128,8 +130,8 @@ def view_vote_districts_map_proposal( ) def view_vote_districts_map_counter_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the map of the counter proposal. """ ballot = getattr(self, 'counter_proposal', None) @@ -152,8 +154,8 @@ def view_vote_districts_map_counter_proposal( ) def view_vote_districts_map_tie_breaker( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the map of the tie breaker. """ ballot = getattr(self, 'tie_breaker', None) @@ -177,12 +179,12 @@ def view_vote_districts_map_tie_breaker( ) def view_ballot_as_table( self: Ballot, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the results of the entities of ballot as table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.vote.last_modified) return { @@ -201,8 +203,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_vote_districts_table_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the table by districts of the proposal. """ ballot = getattr(self, 'proposal', None) @@ -225,8 +227,8 @@ def view_vote_districts_table_proposal( ) def view_vote_districts_table_counter_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the table by districts of the counter proposal. """ ballot = getattr(self, 'counter_proposal', None) @@ -249,8 +251,8 @@ def view_vote_districts_table_counter_proposal( ) def view_vote_districts_table_tie_breaker( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the table of the tie breaker by districts. """ ballot = getattr(self, 'tie_breaker', None) @@ -273,8 +275,8 @@ def view_vote_districts_table_tie_breaker( ) def view_ballot_by_district( self: Ballot, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ Returns the data for the ballot map. """ return get_ballot_data_by_district(self) # type:ignore[return-value] @@ -288,12 +290,12 @@ def view_ballot_by_district( ) def view_ballot_districts_as_map( self: Ballot, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the results of the districts of ballot as map. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.vote.last_modified) layout = VoteLayout(self.vote, request, f'{self.type}-districts') @@ -319,8 +321,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_ballot_districts_svg( self: Ballot, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" Download the results of the districts of ballot as a SVG. """ diff --git a/src/onegov/election_day/views/vote/entities.py b/src/onegov/election_day/views/vote/entities.py index 9c351d2d3a..c8e6f7a045 100644 --- a/src/onegov/election_day/views/vote/entities.py +++ b/src/onegov/election_day/views/vote/entities.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import VoteLayout @@ -25,8 +27,8 @@ ) def view_vote_entities( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view (proposal). """ layout = VoteLayout(self, request, 'entities') @@ -45,8 +47,8 @@ def view_vote_entities( ) def view_vote_entities_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view (proposal). """ layout = VoteLayout(self, request, 'proposal-entities') @@ -65,8 +67,8 @@ def view_vote_entities_proposal( ) def view_vote_entities_counter_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view (counter-proposal). """ layout = VoteLayout(self, request, 'counter-proposal-entities') @@ -85,8 +87,8 @@ def view_vote_entities_counter_proposal( ) def view_vote_entities_tie_breaker( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The main view (tie-breaker). """ layout = VoteLayout(self, request, 'tie-breaker-entities') @@ -104,8 +106,8 @@ def view_vote_entities_tie_breaker( ) def view_vote_entities_map_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the map of the proposal. """ ballot = getattr(self, 'proposal', None) @@ -128,8 +130,8 @@ def view_vote_entities_map_proposal( ) def view_vote_entities_map_counter_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the map of the counter proposal. """ ballot = getattr(self, 'counter_proposal', None) @@ -152,8 +154,8 @@ def view_vote_entities_map_counter_proposal( ) def view_vote_entities_map_tie_breaker( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the map of the tie breaker. """ ballot = getattr(self, 'tie_breaker', None) @@ -176,8 +178,8 @@ def view_vote_entities_map_tie_breaker( ) def view_ballot_by_entity( self: Ballot, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ Returns the data for the ballot map. """ return get_ballot_data_by_entity(self) # type:ignore[return-value] @@ -191,12 +193,12 @@ def view_ballot_by_entity( ) def view_ballot_entities_as_map( self: Ballot, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the results of the entities of ballot as map. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.vote.last_modified) layout = VoteLayout(self.vote, request, f'{self.type}-entities') @@ -223,12 +225,12 @@ def add_last_modified(response: 'Response') -> None: ) def view_ballot_as_table( self: Ballot, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the results of the entities of ballot as table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.vote.last_modified) return { @@ -247,8 +249,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_vote_entities_table_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the table by entities of the proposal. """ ballot = getattr(self, 'proposal', None) @@ -271,8 +273,8 @@ def view_vote_entities_table_proposal( ) def view_vote_entities_table_counter_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the table by entities of the counter proposal. """ ballot = getattr(self, 'counter_proposal', None) @@ -295,8 +297,8 @@ def view_vote_entities_table_counter_proposal( ) def view_vote_entities_table_tie_breaker( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the table of the tie breaker. """ ballot = getattr(self, 'tie_breaker', None) @@ -319,8 +321,8 @@ def view_vote_entities_table_tie_breaker( ) def view_ballot_entities_svg( self: Ballot, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ Download the results of the entities of ballot as a SVG. """ layout = VoteLayout( diff --git a/src/onegov/election_day/views/vote/main.py b/src/onegov/election_day/views/vote/main.py index 827b9b59d8..cc7020fa65 100644 --- a/src/onegov/election_day/views/vote/main.py +++ b/src/onegov/election_day/views/vote/main.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import defaultdict from morepath import redirect from onegov.core.utils import normalize_for_url @@ -28,11 +30,11 @@ ) def view_vote_head( self: Vote, - request: 'ElectionDayRequest' + request: ElectionDayRequest ) -> None: @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, self.last_modified) @@ -43,8 +45,8 @@ def add_headers(response: 'Response') -> None: ) def view_vote( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """" The main view. """ return redirect(VoteLayout(self, request).main_view) @@ -57,15 +59,15 @@ def view_vote( ) def view_vote_json( self: Vote, - request: 'ElectionDayRequest' -) -> 'VoteJson': + request: ElectionDayRequest +) -> VoteJson: """" The main view as JSON. """ last_modified = self.last_modified assert last_modified is not None @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, last_modified) @@ -187,12 +189,12 @@ def add_headers(response: 'Response') -> None: ) def view_vote_summary( self: Vote, - request: 'ElectionDayRequest' -) -> 'JSON_ro': + request: ElectionDayRequest +) -> JSON_ro: """ View the summary of the vote as JSON. """ @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: add_cors_header(response) add_last_modified_header(response, self.last_modified) @@ -206,8 +208,8 @@ def add_headers(response: 'Response') -> None: ) def view_vote_pdf( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ View the generated PDF. """ layout = VoteLayout(self, request) @@ -225,12 +227,12 @@ def view_vote_pdf( ) def view_vote_header_as_widget( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """ A static link to the top bar showing the vote result as widget. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.last_modified) return { diff --git a/src/onegov/election_day/views/vote/statistics.py b/src/onegov/election_day/views/vote/statistics.py index 041ccffcb7..4608ba7013 100644 --- a/src/onegov/election_day/views/vote/statistics.py +++ b/src/onegov/election_day/views/vote/statistics.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.election_day import ElectionDayApp from onegov.election_day.layouts import VoteLayout @@ -23,8 +25,8 @@ ) def view_vote_statistics( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The statistics view (simple vote). """ return { @@ -41,8 +43,8 @@ def view_vote_statistics( ) def view_vote_statistics_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The statistics view (proposal). """ return { @@ -59,8 +61,8 @@ def view_vote_statistics_proposal( ) def view_vote_statistics_counter_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The statistics view (counter-proposal). """ return { @@ -77,8 +79,8 @@ def view_vote_statistics_counter_proposal( ) def view_vote_statistics_tie_breaker( self: Vote, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" The statistics view (tie-breaker). """ return { @@ -95,12 +97,12 @@ def view_vote_statistics_tie_breaker( ) def view_ballot_as_statistics_table( self: Ballot, - request: 'ElectionDayRequest' -) -> 'RenderData': + request: ElectionDayRequest +) -> RenderData: """" View the statistics of the entities of ballot as table. """ @request.after - def add_last_modified(response: 'Response') -> None: + def add_last_modified(response: Response) -> None: add_last_modified_header(response, self.vote.last_modified) return { @@ -119,8 +121,8 @@ def add_last_modified(response: 'Response') -> None: ) def view_vote_statistics_table_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the statistics table of the proposal. """ @@ -144,8 +146,8 @@ def view_vote_statistics_table_proposal( ) def view_vote_statistics_table_counter_proposal( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the statistics table of the counter proposal. """ @@ -169,8 +171,8 @@ def view_vote_statistics_table_counter_proposal( ) def view_vote_statistics_table_tie_breaker( self: Vote, - request: 'ElectionDayRequest' -) -> 'Response': + request: ElectionDayRequest +) -> Response: """ A static link to the statistics table of the tie breaker. """ diff --git a/src/onegov/event/__init__.py b/src/onegov/event/__init__.py index 29d2d21186..22235c7f03 100644 --- a/src/onegov/event/__init__.py +++ b/src/onegov/event/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.event') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/event/cli.py b/src/onegov/event/cli.py index fdd410266b..89213d74b4 100644 --- a/src/onegov/event/cli.py +++ b/src/onegov/event/cli.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import click import hashlib import pycurl @@ -52,8 +54,8 @@ @cli.command('clear') @pass_group_context def clear( - group_context: 'GroupContext' -) -> 'Callable[[CoreRequest, Framework], None]': + group_context: GroupContext +) -> Callable[[CoreRequest, Framework], None]: """ Deletes all events. .. code-block:: bash @@ -62,7 +64,7 @@ def clear( """ - def _clear(request: 'CoreRequest', app: 'Framework') -> None: + def _clear(request: CoreRequest, app: Framework) -> None: if not click.confirm('Do you really want to remove all events?'): abort('Deletion process aborted') @@ -165,11 +167,11 @@ def get_event_dates(url: str, timezone: str) -> tuple[datetime, datetime]: @click.option('--tagmap', 'tagmap_file', type=click.File()) @click.option('--clear/-no-clear', default=False) def import_json( - group_context: 'GroupContext', + group_context: GroupContext, url: str, - tagmap_file: 'TextIOWrapper | None', + tagmap_file: TextIOWrapper | None, clear: bool -) -> 'Callable[[CoreRequest, Framework], None]': +) -> Callable[[CoreRequest, Framework], None]: r""" Fetches the events from a seantis.dir.events instance. This command is intended for migration and to be removed in the future. @@ -186,7 +188,7 @@ def import_json( else: tagmap = None - def _import_json(request: 'CoreRequest', app: 'Framework') -> None: + def _import_json(request: CoreRequest, app: Framework) -> None: unknown_tags = set() response = get(url, timeout=60) @@ -328,9 +330,9 @@ def _import_json(request: 'CoreRequest', app: 'Framework') -> None: def filter_cb( - ctx: 'click.Context', - param: 'click.Parameter', - value: 'tuple[str, list[str]] | None' + ctx: click.Context, + param: click.Parameter, + value: tuple[str, list[str]] | None ) -> dict[str, list[str]] | None: if not value: return {} @@ -349,14 +351,14 @@ def filter_cb( type=(str, StringListParamType(' ')), callback=filter_cb, help='filter in the form: -f fil-name fil-val-1,fil-val-2') def import_ical( - group_context: 'GroupContext', - ical: 'TextIOWrapper', + group_context: GroupContext, + ical: TextIOWrapper, future_events_only: bool = False, - event_image: 'FileIO | None' = None, - categories: 'Sequence[str]' = (), - keyword_filters: 'dict[str, list[str]] | None' = None + event_image: FileIO | None = None, + categories: Sequence[str] = (), + keyword_filters: dict[str, list[str]] | None = None -) -> 'Callable[[CoreRequest, Framework], None]': +) -> Callable[[CoreRequest, Framework], None]: r""" Imports events from an iCalendar file. Examples: @@ -389,7 +391,7 @@ def import_ical( """ cat = list(categories) - def _import_ical(request: 'CoreRequest', app: 'Framework') -> None: + def _import_ical(request: CoreRequest, app: Framework) -> None: collection = EventCollection(app.session()) added, updated, purged = collection.from_ical( ical.read(), future_events_only, event_image, @@ -410,11 +412,11 @@ def _import_ical(request: 'CoreRequest', app: 'Framework') -> None: @click.option('--tagmap', 'tagmap_file', type=click.File()) @click.option('--clear', is_flag=True, default=False) def import_guidle( - group_context: 'GroupContext', + group_context: GroupContext, url: str, - tagmap_file: 'TextIOWrapper | None', + tagmap_file: TextIOWrapper | None, clear: bool -) -> 'Callable[[CoreRequest, Framework], None]': +) -> Callable[[CoreRequest, Framework], None]: """ Fetches the events from guidle. Example: @@ -429,7 +431,7 @@ def import_guidle( else: tagmap = None - def _import_guidle(request: 'CoreRequest', app: 'Framework') -> None: + def _import_guidle(request: CoreRequest, app: Framework) -> None: try: response = get(url, timeout=300) response.raise_for_status() @@ -464,7 +466,7 @@ def _import_guidle(request: 'CoreRequest', app: 'Framework') -> None: def items( unknown_tags: set[str] - ) -> 'Iterator[EventImportItem | str]': + ) -> Iterator[EventImportItem | str]: for offer in GuidleExportData(root).offers(): source = f'{prefix}-{offer.uid}.0' diff --git a/src/onegov/event/collections/__init__.py b/src/onegov/event/collections/__init__.py index f7a0ceeda6..0b1932fe6c 100644 --- a/src/onegov/event/collections/__init__.py +++ b/src/onegov/event/collections/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.event.collections.events import EventCollection from onegov.event.collections.occurrences import OccurrenceCollection diff --git a/src/onegov/event/collections/events.py b/src/onegov/event/collections/events.py index 0a50e4ded9..c64d20696b 100644 --- a/src/onegov/event/collections/events.py +++ b/src/onegov/event/collections/events.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import hashlib from datetime import date @@ -53,9 +55,9 @@ class EventCollection(Pagination[Event]): def __init__( self, - session: 'Session', + session: Session, page: int = 0, - state: 'EventState | None' = None + state: EventState | None = None ) -> None: super().__init__(page) @@ -69,22 +71,22 @@ def __eq__(self, other: object) -> bool: and self.page == other.page ) - def subset(self) -> 'Query[Event]': + def subset(self) -> Query[Event]: return self.query() @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__(self.session, index, self.state) - def for_state(self, state: 'EventState | None') -> 'Self': + def for_state(self, state: EventState | None) -> Self: """ Returns a new instance of the collection with the given state. """ return self.__class__(self.session, 0, state) - def query(self) -> 'Query[Event]': + def query(self) -> Query[Event]: query = self.session.query(Event) if self.state: query = query.filter(Event.state == self.state) @@ -178,20 +180,20 @@ def by_name(self, name: str) -> Event | None: query = self.session.query(Event).filter(Event.name == name) return query.first() - def by_id(self, id: 'UUID') -> Event | None: + def by_id(self, id: UUID) -> Event | None: """ Return an event by its id. Hex representations work as well. """ query = self.session.query(Event).filter(Event.id == id) return query.first() def from_import( self, - items: 'Iterable[EventImportItem | str]', + items: Iterable[EventImportItem | str], purge: str | None = None, publish_immediately: bool = True, - valid_state_transfers: 'Mapping[str, str] | None' = None, + valid_state_transfers: Mapping[str, str] | None = None, published_only: bool = False, future_events_only: bool = False - ) -> tuple[list[Event], list[Event], list['UUID']]: + ) -> tuple[list[Event], list[Event], list[UUID]]: """ Add or updates the given events. Only updates events which have changed. Uses ``Event.source_updated`` @@ -351,11 +353,11 @@ def from_ical( self, ical: str, future_events_only: bool = False, - event_image: 'IO[bytes] | None' = None, + event_image: IO[bytes] | None = None, event_image_name: str | None = None, default_categories: list[str] | None = None, default_filter_keywords: dict[str, list[str]] | None = None - ) -> tuple[list[Event], list[Event], list['UUID']]: + ) -> tuple[list[Event], list[Event], list[UUID]]: """ Imports the events from an iCalender string. We assume the timezone to be Europe/Zurich! @@ -482,7 +484,7 @@ def from_ical( def as_anthrazit_xml( self, - request: 'CoreRequest', + request: CoreRequest, future_events_only: bool = True ) -> str: """ diff --git a/src/onegov/event/collections/occurrences.py b/src/onegov/event/collections/occurrences.py index cc42d4dd26..7e545af75c 100644 --- a/src/onegov/event/collections/occurrences.py +++ b/src/onegov/event/collections/occurrences.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import defaultdict from datetime import date, timedelta, datetime @@ -103,19 +105,19 @@ class OccurrenceCollection(Pagination[Occurrence]): def __init__( self, - session: 'Session', + session: Session, page: int = 0, range: DateRange | None = None, start: date | None = None, end: date | None = None, outdated: bool = False, - tags: 'Sequence[str] | None' = None, - filter_keywords: 'Mapping[str, list[str] | str] | None' = None, - locations: 'Sequence[str] | None' = None, + tags: Sequence[str] | None = None, + filter_keywords: Mapping[str, list[str] | str] | None = None, + locations: Sequence[str] | None = None, only_public: bool = False, - search_widget: 'OccurenceSearchWidget | None' = None, + search_widget: OccurenceSearchWidget | None = None, event_filter_configuration: dict[str, Any] | None = None, - event_filter_fields: 'Sequence[ParsedField] | None' = None, + event_filter_fields: Sequence[ParsedField] | None = None, ) -> None: super().__init__(page=page) @@ -134,7 +136,7 @@ def __init__( def __eq__(self, other: object) -> bool: return isinstance(other, self.__class__) and self.page == other.page - def subset(self) -> 'Query[Occurrence]': + def subset(self) -> Query[Occurrence]: return self.query() @property @@ -142,7 +144,7 @@ def search(self) -> str | None: return self.search_widget.name if self.search_widget else None @property - def search_query(self) -> 'Query[Occurrence] | None': + def search_query(self) -> Query[Occurrence] | None: return self.search_widget.search_query if self.search_widget else None @property @@ -278,12 +280,12 @@ def for_filter( self, *, range: DateRange | None = None, - start: 'date | MissingType | None' = MISSING, - end: 'date | MissingType | None' = MISSING, + start: date | MissingType | None = MISSING, + end: date | MissingType | None = MISSING, outdated: bool | None = None, - tags: 'Sequence[str] | None' = None, + tags: Sequence[str] | None = None, tag: str | None = None, - locations: 'Sequence[str] | None' = None, + locations: Sequence[str] | None = None, location: str | None = None, ) -> Self: """ Returns a new instance of the collection with the given filters @@ -390,15 +392,15 @@ def set_event_filter_configuration( def set_event_filter_fields( self, - fields: 'Sequence[ParsedField] | None' + fields: Sequence[ParsedField] | None ) -> None: self.event_filter_fields = fields or () def valid_keywords( self, - parameters: 'Mapping[str, T]' - ) -> dict[str, 'T']: + parameters: Mapping[str, T] + ) -> dict[str, T]: valid_keywords = { as_internal_id(kw) @@ -413,8 +415,8 @@ def valid_keywords( def available_filters( self, sort_choices: bool = False, - sortfunc: 'Callable[[str], SupportsRichComparison] | None ' = None - ) -> 'Iterable[tuple[str, str, list[str]]]': + sortfunc: Callable[[str], SupportsRichComparison] | None = None + ) -> Iterable[tuple[str, str, list[str]]]: """ Retrieve the filters with their choices. Return by default in the order of how they are defined in the config structure. @@ -440,7 +442,7 @@ def available_filters( ) } - def maybe_sorted(values: 'Iterable[str]') -> list[str]: + def maybe_sorted(values: Iterable[str]) -> list[str]: if not sort_choices: return list(values) return sorted(values, key=sortfunc) @@ -464,7 +466,7 @@ def used_tags(self) -> set[str]: ).filter(func.DATE(Occurrence.end) >= date.today()) return {key[0] for key in query.distinct()} - def query(self) -> 'Query[Occurrence]': + def query(self) -> Query[Occurrence]: """ Queries occurrences with the set parameters. Finds occurrences which: @@ -596,7 +598,7 @@ def by_name(self, name: str) -> Occurrence | None: query = self.session.query(Occurrence).filter(Occurrence.name == name) return query.first() - def as_ical(self, request: 'CoreRequest') -> bytes: + def as_ical(self, request: CoreRequest) -> bytes: """ Returns the the events of the given occurrences as iCalendar string. @@ -698,7 +700,7 @@ class Tags(etree.ElementBase): used as tag name. """ - def __init__(self, tags: 'Sequence[str]' = ()) -> None: # type:ignore + def __init__(self, tags: Sequence[str] = ()) -> None: # type:ignore super().__init__() self.tag = 'tags' diff --git a/src/onegov/event/models/__init__.py b/src/onegov/event/models/__init__.py index 37bd31c9a8..f10834c518 100644 --- a/src/onegov/event/models/__init__.py +++ b/src/onegov/event/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.event.models.event import Event, EventFile from onegov.event.models.occurrence import Occurrence diff --git a/src/onegov/event/models/event.py b/src/onegov/event/models/event.py index 402b272065..7cce226708 100644 --- a/src/onegov/event/models/event.py +++ b/src/onegov/event/models/event.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import warnings from datetime import datetime @@ -76,14 +78,14 @@ class Event(Base, OccurrenceMixin, TimestampMixin, SearchableContent, occurrence_dates_year_limit = 2 #: Internal number of the event - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: State of the event - state: 'Column[EventState]' = Column( + state: Column[EventState] = Column( Enum( # type: ignore[arg-type] 'initiated', 'submitted', 'published', 'withdrawn', name='event_state' @@ -93,39 +95,39 @@ class Event(Base, OccurrenceMixin, TimestampMixin, SearchableContent, ) #: description of the event - description: 'dict_property[str | None]' = content_property() + description: dict_property[str | None] = content_property() #: the event organizer - organizer: 'dict_property[str | None]' = content_property() + organizer: dict_property[str | None] = content_property() #: the event organizer's public e-mail address - organizer_email: 'dict_property[str | None]' = content_property() + organizer_email: dict_property[str | None] = content_property() #: the event organizer's phone number - organizer_phone: 'dict_property[str | None]' = content_property() + organizer_phone: dict_property[str | None] = content_property() #: an external url for the event - external_event_url: 'dict_property[str | None]' = content_property() + external_event_url: dict_property[str | None] = content_property() #: an external url for the event - event_registration_url: 'dict_property[str | None]' = content_property() + event_registration_url: dict_property[str | None] = content_property() #: the price of the event (a text field, not an amount) - price: 'dict_property[str | None]' = content_property() + price: dict_property[str | None] = content_property() #: the source of the event, if imported - source: 'dict_property[str | None]' = meta_property() + source: dict_property[str | None] = meta_property() #: when the source of the event was last updated (if imported) - source_updated: 'dict_property[str | None]' = meta_property() + source_updated: dict_property[str | None] = meta_property() #: Recurrence of the event (RRULE, see RFC2445) - recurrence: 'Column[str | None]' = Column(Text, nullable=True) + recurrence: Column[str | None] = Column(Text, nullable=True) #: The access property of the event, taken from onegov.org. Not ideal to #: have this defined here, instead of using an AccessExtension, but that #: would only be possible with deeper changes to the Event model. - access: 'dict_property[str]' = meta_property(default='public') + access: dict_property[str] = meta_property(default='public') #: The associated image image = associated( @@ -179,7 +181,7 @@ def set_blob( setattr(self, blob, None) #: Occurrences of the event - occurrences: 'relationship[list[Occurrence]]' = relationship( + occurrences: relationship[list[Occurrence]] = relationship( 'Occurrence', cascade='all, delete-orphan', back_populates='event', @@ -202,7 +204,7 @@ def es_public(self) -> bool: def es_skip(self) -> bool: return self.state != 'published' or getattr(self, '_es_skip', False) - def source_url(self, request: 'CoreRequest') -> str | None: + def source_url(self, request: CoreRequest) -> str | None: """ Returns an url pointing to the external event if imported. """ if not self.source or not self.source.startswith('guidle'): return None @@ -221,7 +223,7 @@ def __setattr__(self, name: str, value: object) -> None: self._update_occurrences() @property - def base_query(self) -> 'Query[Occurrence]': + def base_query(self) -> Query[Occurrence]: session = object_session(self) return session.query(Occurrence).filter_by(event_id=self.id) @@ -253,7 +255,7 @@ def future_occurrences( self, offset: int = 0, limit: int = 10 - ) -> 'Query[Occurrence]': + ) -> Query[Occurrence]: return self.base_query.filter( Occurrence.start >= utcnow() @@ -460,7 +462,7 @@ def withdraw(self) -> None: assert self.state in ('submitted', 'published') self.state = 'withdrawn' - def get_ical_vevents(self, url: str | None = None) -> 'Iterator[vEvent]': + def get_ical_vevents(self, url: str | None = None) -> Iterator[vEvent]: """ Returns the event and all its occurrences as icalendar objects. If the calendar has a bunch of RDATE's instead of a proper RRULE, we diff --git a/src/onegov/event/models/mixins.py b/src/onegov/event/models/mixins.py index ac493971f7..6e8a3e553c 100644 --- a/src/onegov/event/models/mixins.py +++ b/src/onegov/event/models/mixins.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from onegov.core.orm.mixins import content_property, ContentMixin @@ -28,17 +30,20 @@ class OccurrenceMixin(ContentMixin): """ #: Title of the event - title: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) #: A nice id for the url, readable by humans - name: 'Column[str | None]' = Column(Text) + name: Column[str | None] = Column(Text) #: Description of the location of the event - location: 'Column[str | None]' = Column(Text, nullable=True) + location: Column[str | None] = Column(Text, nullable=True) #: Tags/Categories of the event - _tags: 'Column[dict[str, str] | None]' = Column( # type:ignore - MutableDict.as_mutable(HSTORE), nullable=True, name='tags') + _tags: Column[dict[str, str] | None] = Column( # type:ignore + MutableDict.as_mutable(HSTORE), # type:ignore[no-untyped-call] + nullable=True, + name='tags' + ) @property def tags(self) -> list[str]: @@ -50,30 +55,30 @@ def tags(self) -> list[str]: # be able to set this with arbitrary iterables we need # to define a custom descriptor @tags.setter - def tags(self, value: 'Iterable[str]') -> None: + def tags(self, value: Iterable[str]) -> None: self._tags = {key.strip(): '' for key in value} #: Filter keywords if organisation settings enabled filters - filter_keywords: 'dict_property[dict[str, list[str] | str]]' + filter_keywords: dict_property[dict[str, list[str] | str]] filter_keywords = content_property(default=dict) #: Timezone of the event - timezone: 'Column[str]' = Column(String, nullable=False) + timezone: Column[str] = Column(String, nullable=False) #: Start date and time of the event (of the first event if recurring) - start: 'Column[datetime]' = Column(UTCDateTime, nullable=False) + start: Column[datetime] = Column(UTCDateTime, nullable=False) @property - def localized_start(self) -> 'datetime': + def localized_start(self) -> datetime: """ The localized version of the start date/time. """ return to_timezone(self.start, self.timezone) #: End date and time of the event (of the first event if recurring) - end: 'Column[datetime]' = Column(UTCDateTime, nullable=False) + end: Column[datetime] = Column(UTCDateTime, nullable=False) @property - def localized_end(self) -> 'datetime': + def localized_end(self) -> datetime: """ The localized version of the end date/time. """ return to_timezone(self.end, self.timezone) diff --git a/src/onegov/event/models/occurrence.py b/src/onegov/event/models/occurrence.py index 30b6925ea9..4ea42db75c 100644 --- a/src/onegov/event/models/occurrence.py +++ b/src/onegov/event/models/occurrence.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from icalendar import Calendar as vCalendar from icalendar import Event as vEvent from onegov.core.orm import Base @@ -26,20 +28,20 @@ class Occurrence(Base, OccurrenceMixin, TimestampMixin): __tablename__ = 'event_occurrences' #: Internal number of the occurence - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type: ignore[arg-type] primary_key=True, default=uuid4 ) #: Event this occurrence belongs to - event_id: 'Column[uuid.UUID]' = Column( + event_id: Column[uuid.UUID] = Column( UUID, # type: ignore[arg-type] ForeignKey('events.id'), nullable=False ) - event: 'relationship[Event]' = relationship( + event: relationship[Event] = relationship( 'Event', back_populates='occurrences', ) diff --git a/src/onegov/event/upgrade.py b/src/onegov/event/upgrade.py index 982f71a4be..f0b7e66c6f 100644 --- a/src/onegov/event/upgrade.py +++ b/src/onegov/event/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + from onegov.core.orm.types import JSON from onegov.core.upgrade import upgrade_task, UpgradeContext from onegov.event import EventCollection diff --git a/src/onegov/event/utils/__init__.py b/src/onegov/event/utils/__init__.py index b1550c0de6..e5552c062d 100644 --- a/src/onegov/event/utils/__init__.py +++ b/src/onegov/event/utils/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.event.utils.guidle import GuidleExportData from onegov.event.utils.utils import as_rdates diff --git a/src/onegov/event/utils/guidle.py b/src/onegov/event/utils/guidle.py index 4fdd7d8378..a520e016a6 100644 --- a/src/onegov/event/utils/guidle.py +++ b/src/onegov/event/utils/guidle.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from bleach.sanitizer import Cleaner from functools import cached_property from datetime import timedelta @@ -23,7 +25,7 @@ class GuidleBase: """ Base class for parsing guidle exports containing general helpers. """ - def __init__(self, root: '_Element') -> None: + def __init__(self, root: _Element) -> None: self.root = root self.nsmap = {'guidle': 'http://www.guidle.com'} self.cleaner = Cleaner( @@ -36,8 +38,8 @@ def __init__(self, root: '_Element') -> None: def find( self, path: str, - root: '_Element | None' = None - ) -> list['_Element']: + root: _Element | None = None + ) -> list[_Element]: """ Gets the elements with the given path. """ root = root if root is not None else self.root @@ -47,7 +49,7 @@ def find( def get( self, path: str, - root: '_Element | None' = None, + root: _Element | None = None, joiner: str = ' ', parser: None = None ) -> str: ... @@ -56,19 +58,19 @@ def get( def get( self, path: str, - root: '_Element | None' = None, + root: _Element | None = None, joiner: str = ' ', *, - parser: 'Callable[[str], _T]' - ) -> '_T | None': ... + parser: Callable[[str], _T] + ) -> _T | None: ... def get( self, path: str, - root: '_Element | None' = None, + root: _Element | None = None, joiner: str = ' ', - parser: 'Callable[[str], _T] | None' = None - ) -> '_T | str | None': + parser: Callable[[str], _T] | None = None + ) -> _T | str | None: """ Returns the text of the elements with the given path. Allows to specifiy a joining character and optionally a parser. If no @@ -86,7 +88,7 @@ def get( else: return self.cleaner.clean(result) if result else '' - def join(self, texts: 'Sequence[str]', joiner: str = ', ') -> str: + def join(self, texts: Sequence[str], joiner: str = ', ') -> str: """ Joins a set of text, skips duplicate and empty texts while preserving the order. """ @@ -102,7 +104,7 @@ def join(self, texts: 'Sequence[str]', joiner: str = ', ') -> str: class GuidleExportData(GuidleBase): """ Represents a whole guidle export. """ - def offers(self) -> 'Iterator[GuidleOffer]': + def offers(self) -> Iterator[GuidleOffer]: for offer in self.find('.//guidle:offer'): yield GuidleOffer(offer) @@ -216,7 +218,7 @@ def pdf(self) -> tuple[str, str] | tuple[None, None]: def tags( self, - tagmap: 'Mapping[str, str] | None' = None + tagmap: Mapping[str, str] | None = None ) -> tuple[set[str], set[str]]: """ Returns a set of known and a set of unkonwn tags. """ @@ -238,14 +240,14 @@ def tags( return tags, set() @cached_property - def coordinates(self) -> 'RealCoordinates | None': + def coordinates(self) -> RealCoordinates | None: lat = self.get('guidle:address/guidle:latitude', parser=float) lon = self.get('guidle:address/guidle:longitude', parser=float) if lat is not None and lon is not None: return Coordinates(lat, lon) return None - def schedules(self) -> 'Iterator[GuidleScheduleDate]': + def schedules(self) -> Iterator[GuidleScheduleDate]: for schedule in self.find('guidle:schedules/guidle:date'): yield GuidleScheduleDate(schedule) @@ -253,7 +255,7 @@ def schedules(self) -> 'Iterator[GuidleScheduleDate]': class GuidleScheduleDate(GuidleBase): """ Represents a single schedule date of an offer. """ - def __init__(self, root: '_Element') -> None: + def __init__(self, root: _Element) -> None: super().__init__(root) # Parse start date, end date and recurrence diff --git a/src/onegov/event/utils/utils.py b/src/onegov/event/utils/utils.py index adefe6bd46..186507fd0c 100644 --- a/src/onegov/event/utils/utils.py +++ b/src/onegov/event/utils/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from dateutil.rrule import rrulestr from sedate import standardize_date from datetime import date diff --git a/src/onegov/feriennet/__init__.py b/src/onegov/feriennet/__init__.py index d090ce01d9..baf032e49e 100644 --- a/src/onegov/feriennet/__init__.py +++ b/src/onegov/feriennet/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.feriennet') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/feriennet/app.py b/src/onegov/feriennet/app.py index fd38ed6c6a..7a97c48569 100644 --- a/src/onegov/feriennet/app.py +++ b/src/onegov/feriennet/app.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from markupsafe import Markup from onegov.activity import ( @@ -116,15 +118,15 @@ def user_titles_by_name(self) -> dict[str, str]: User.username, User.title)) @orm_cached(policy='on-table-change:users') - def user_ids_by_name(self) -> dict[str | None, 'UUID']: + def user_ids_by_name(self) -> dict[str | None, UUID]: return dict(UserCollection(self.session()).query().with_entities( User.username, User.id)) @cached_property - def sponsors(self) -> list['Sponsor']: + def sponsors(self) -> list[Sponsor]: return load_sponsors(utils.module_path('onegov.feriennet', 'sponsors')) - def mail_sponsor(self, request: FeriennetRequest) -> list['Sponsor']: + def mail_sponsor(self, request: FeriennetRequest) -> list[Sponsor]: sponsors = [ sponsor.compiled(request) for sponsor in self.sponsors if getattr(sponsor, 'mail_url', None) @@ -143,13 +145,13 @@ def default_period(self) -> PeriodMeta | None: return self.periods[0] if self.periods else None @property - def public_organiser_data(self) -> 'Sequence[str]': + def public_organiser_data(self) -> Sequence[str]: return self.org.meta.get('public_organiser_data', ('name', 'website')) def get_sponsors( self, request: FeriennetRequest - ) -> list['Sponsor'] | None: + ) -> list[Sponsor] | None: assert request.locale is not None language = request.locale[:2] @@ -218,8 +220,8 @@ def invoice_schema_config(self) -> tuple[str, dict[str, Any] | None]: def invoice_collection( self, - period_id: 'UUID | None' = None, - user_id: 'UUID | None' = None + period_id: UUID | None = None, + user_id: UUID | None = None ) -> InvoiceCollection: """ Returns the invoice collection guaranteed to be configured according to the organisation's settings. @@ -247,7 +249,7 @@ def show_donate(self) -> bool: # FIXME: Are we still using these properties? Because they were broken @property - def donation_amounts(self) -> 'Sequence[int]': + def donation_amounts(self) -> Sequence[int]: return self.org.meta.get('donation_amounts', DEFAULT_DONATION_AMOUNTS) def show_volunteers(self, request: FeriennetRequest) -> bool: @@ -273,22 +275,22 @@ def get_template_directory() -> str: @FeriennetApp.setting(section='org', name='create_new_organisation') def get_create_new_organisation_factory( -) -> 'Callable[[FeriennetApp, str], Organisation]': +) -> Callable[[FeriennetApp, str], Organisation]: return create_new_organisation @FeriennetApp.setting(section='org', name='status_mail_roles') -def get_status_mail_roles() -> 'Sequence[str]': +def get_status_mail_roles() -> Sequence[str]: return ('admin', ) @FeriennetApp.setting(section='org', name='ticket_manager_roles') -def get_ticket_manager_roles() -> 'Sequence[str]': +def get_ticket_manager_roles() -> Sequence[str]: return ('admin', ) @FeriennetApp.setting(section='org', name='public_ticket_messages') -def get_public_ticket_messages() -> 'Sequence[str]': +def get_public_ticket_messages() -> Sequence[str]: return (*default_public_ticket_messages(), 'activity') @@ -299,7 +301,7 @@ def get_require_complete_userprofile() -> bool: @FeriennetApp.setting(section='org', name='is_complete_userprofile') def get_is_complete_userprofile_handler( -) -> 'Callable[[FeriennetRequest, str], bool]': +) -> Callable[[FeriennetRequest, str], bool]: from onegov.feriennet.forms import UserProfileForm def is_complete_userprofile( @@ -350,12 +352,12 @@ def get_js_path() -> str: @FeriennetApp.webasset('volunteer-cart') -def get_volunteer_cart() -> 'Iterator[str]': +def get_volunteer_cart() -> Iterator[str]: yield 'volunteer-cart.jsx' @FeriennetApp.webasset('common') -def get_common_asset() -> 'Iterator[str]': +def get_common_asset() -> Iterator[str]: yield from default_common_asset() yield 'reloadfrom.js' yield 'printthis.js' @@ -365,7 +367,7 @@ def get_common_asset() -> 'Iterator[str]': @FeriennetApp.setting(section='content_security_policy', name='default') -def feriennet_content_security_policy() -> 'ContentSecurityPolicy': +def feriennet_content_security_policy() -> ContentSecurityPolicy: policy = org_content_security_policy() policy.connect_src.add('https://*.piwik.pro') return policy diff --git a/src/onegov/feriennet/boardlets.py b/src/onegov/feriennet/boardlets.py index 93f6f4f16f..4b434cebd8 100644 --- a/src/onegov/feriennet/boardlets.py +++ b/src/onegov/feriennet/boardlets.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from decimal import Decimal from functools import cached_property from onegov.activity import Activity, Attendee, Booking, Occasion @@ -22,14 +24,14 @@ class FeriennetBoardlet(Boardlet): - request: 'FeriennetRequest' + request: FeriennetRequest @cached_property - def session(self) -> 'Session': + def session(self) -> Session: return self.request.session @cached_property - def period(self) -> 'PeriodMeta | None': + def period(self) -> PeriodMeta | None: return self.request.app.active_period @cached_property @@ -62,7 +64,7 @@ def state(self) -> Literal['success', 'failure']: return 'success' @property - def facts(self) -> 'Iterator[BoardletFact]': + def facts(self) -> Iterator[BoardletFact]: if not self.period: return @@ -104,7 +106,7 @@ def icon(checked: bool) -> str: class ActivitiesBoardlet(FeriennetBoardlet): @cached_property - def occasions(self) -> 'Query[Occasion]': + def occasions(self) -> Query[Occasion]: assert self.period is not None return self.session.query(Occasion).filter_by( period_id=self.period.id).join( @@ -131,7 +133,7 @@ def activities_count(self) -> int: ) ).filter_by(state='accepted').scalar() - def occasion_states(self) -> dict['OccasionState', int]: + def occasion_states(self) -> dict[OccasionState, int]: occasion_states: dict[OccasionState, int] = { 'overfull': 0, 'full': 0, @@ -174,7 +176,7 @@ def state(self) -> Literal['success', 'warning', 'failure']: return self.activities_count and 'success' or 'warning' @property - def facts(self) -> 'Iterator[BoardletFact]': + def facts(self) -> Iterator[BoardletFact]: if not self.period: return @@ -247,7 +249,7 @@ def facts(self) -> 'Iterator[BoardletFact]': class BookingsBoardlet(FeriennetBoardlet): @cached_property - def counts(self) -> dict['BookingState | Literal["total"]', int]: + def counts(self) -> dict[BookingState | Literal['total'], int]: counts: dict[BookingState | Literal['total'], int] = { 'accepted': 0, 'blocked': 0, @@ -300,7 +302,7 @@ def state(self) -> Literal['success', 'warning', 'failure']: return self.counts['total'] and 'success' or 'warning' @property - def facts(self) -> 'Iterator[BoardletFact]': + def facts(self) -> Iterator[BoardletFact]: if not self.period: return @@ -418,7 +420,7 @@ def state(self) -> Literal['success', 'warning', 'failure']: return self.attendee_counts['total'] and 'success' or 'warning' @property - def facts(self) -> 'Iterator[BoardletFact]': + def facts(self) -> Iterator[BoardletFact]: if not self.period: return @@ -480,7 +482,7 @@ def state(self) -> Literal['success', 'warning', 'failure']: return self.happiness > 75 and 'success' or 'warning' @property - def facts(self) -> 'Iterator[BoardletFact]': + def facts(self) -> Iterator[BoardletFact]: if not self.period: return @@ -536,7 +538,7 @@ def state(self) -> Literal['success', 'warning', 'failure']: return self.amounts['outstanding'] and 'warning' or 'success' @property - def facts(self) -> 'Iterator[BoardletFact]': + def facts(self) -> Iterator[BoardletFact]: if not self.period: return diff --git a/src/onegov/feriennet/cli.py b/src/onegov/feriennet/cli.py index 33b1b7c228..9930b9d2c6 100644 --- a/src/onegov/feriennet/cli.py +++ b/src/onegov/feriennet/cli.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import click import sys @@ -21,7 +23,7 @@ @click.argument('title') def delete_period( title: str -) -> 'Callable[[FeriennetRequest, FeriennetApp], None]': +) -> Callable[[FeriennetRequest, FeriennetApp], None]: """ Deletes all the data associated with a period, including: * Payments @@ -41,8 +43,8 @@ def delete_period( """ def delete_period( - request: 'FeriennetRequest', - app: 'FeriennetApp' + request: FeriennetRequest, + app: FeriennetApp ) -> None: period = request.session.query(Period).filter_by(title=title).first() @@ -150,7 +152,7 @@ def delete_period( @cli.command(name='compute-occasion-durations') def compute_occasion_durations( -) -> 'Callable[[FeriennetRequest, FeriennetApp], None]': +) -> Callable[[FeriennetRequest, FeriennetApp], None]: """ Recomputes the durations of all occassions. Example:: @@ -160,8 +162,8 @@ def compute_occasion_durations( """ def compute_occasion_durations( - request: 'FeriennetRequest', - app: 'FeriennetApp' + request: FeriennetRequest, + app: FeriennetApp ) -> None: occasions = request.session.query(Occasion) diff --git a/src/onegov/feriennet/collections/__init__.py b/src/onegov/feriennet/collections/__init__.py index 8b3bda816d..d8bddc887d 100644 --- a/src/onegov/feriennet/collections/__init__.py +++ b/src/onegov/feriennet/collections/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.feriennet.collections.activity import VacationActivityCollection from onegov.feriennet.collections.billing import BillingCollection from onegov.feriennet.collections.match import MatchCollection diff --git a/src/onegov/feriennet/collections/activity.py b/src/onegov/feriennet/collections/activity.py index 75e89c75de..b5b7636e05 100644 --- a/src/onegov/feriennet/collections/activity.py +++ b/src/onegov/feriennet/collections/activity.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import ActivityCollection from onegov.feriennet.policy import ActivityQueryPolicy from sqlalchemy.orm import joinedload @@ -19,11 +21,11 @@ class VacationActivityCollection(ActivityCollection['VacationActivity']): # type is ignored, but present to keep the same signature as the superclass def __init__( self, - session: 'Session', + session: Session, type: None = None, pages: tuple[int, int] | None = (0, 0), - filter: 'ActivityFilter | None' = None, - identity: 'Identity | NoIdentity | None' = None + filter: ActivityFilter | None = None, + identity: Identity | NoIdentity | None = None ) -> None: super().__init__( @@ -39,13 +41,13 @@ def __init__( def policy(self) -> ActivityQueryPolicy: return ActivityQueryPolicy.for_identity(self.identity) - def transform_batch_query(self, query: 'Query[T]') -> 'Query[T]': + def transform_batch_query(self, query: Query[T]) -> Query[T]: return query.options(joinedload('occasions')) - def query_base(self) -> 'Query[VacationActivity]': + def query_base(self) -> Query[VacationActivity]: return self.policy.granted_subset(self.session.query(self.model_class)) - def by_page_range(self, page_range: tuple[int, int] | None) -> 'Self': + def by_page_range(self, page_range: tuple[int, int] | None) -> Self: return self.__class__( session=self.session, identity=self.identity, diff --git a/src/onegov/feriennet/collections/billing.py b/src/onegov/feriennet/collections/billing.py index 0245c6a6fd..adcb6513ec 100644 --- a/src/onegov/feriennet/collections/billing.py +++ b/src/onegov/feriennet/collections/billing.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from decimal import Decimal from itertools import groupby @@ -51,8 +53,8 @@ class BillingCollection: def __init__( self, - request: 'FeriennetRequest', - period: 'Period | PeriodMeta', + request: FeriennetRequest, + period: Period | PeriodMeta, username: str | None = None, expand: bool = False, state: Literal['paid', 'unpaid'] | None = None @@ -70,38 +72,38 @@ def __init__( self.state = state @property - def user_id(self) -> 'UUID | None': + def user_id(self) -> UUID | None: if self.username: return self.app.user_ids_by_name[self.username] return None @property - def period_id(self) -> 'UUID': + def period_id(self) -> UUID: return self.period.id - def for_period(self, period: 'Period') -> 'Self': + def for_period(self, period: Period) -> Self: return self.__class__( self.request, period, self.username, self.expand, self.state) - def for_username(self, username: str) -> 'Self': + def for_username(self, username: str) -> Self: return self.__class__( self.request, self.period, username, self.expand, self.state) - def for_expand(self, expand: bool) -> 'Self': + def for_expand(self, expand: bool) -> Self: return self.__class__( self.request, self.period, self.username, expand, self.state) - def for_state(self, state: Literal['paid', 'unpaid'] | None) -> 'Self': + def for_state(self, state: Literal['paid', 'unpaid'] | None) -> Self: return self.__class__( self.request, self.period, self.username, self.expand, state) @property - def invoices_by_period_query(self) -> 'Alias': + def invoices_by_period_query(self) -> Alias: return as_selectable_from_path( module_path('onegov.feriennet', 'queries/invoices_by_period.sql')) @property - def invoices_by_period(self) -> 'Query[InvoicesByPeriodRow]': + def invoices_by_period(self) -> Query[InvoicesByPeriodRow]: invoices = self.invoices_by_period_query.c query = select(invoices).where(invoices.period_id == self.period_id) @@ -115,10 +117,10 @@ def invoices_by_period(self) -> 'Query[InvoicesByPeriodRow]': return self.session.execute(query) class Bill(NamedTuple): - items: tuple['InvoicesByPeriodRow', ...] - first: 'InvoicesByPeriodRow' - id: 'UUID' - invoice_id: 'UUID' + items: tuple[InvoicesByPeriodRow, ...] + first: InvoicesByPeriodRow + id: UUID + invoice_id: UUID title: str paid: bool total: Decimal @@ -165,7 +167,7 @@ def outstanding(self) -> Decimal: def add_position( self, - users: 'Collection[str]', + users: Collection[str], text: str, amount: Decimal, group: str @@ -197,7 +199,7 @@ def add_position( def add_manual_position( self, - users: 'Collection[str]', + users: Collection[str], text: str, amount: Decimal ) -> int: @@ -206,7 +208,7 @@ def add_manual_position( def include_donation( self, text: str, - user_id: 'UUID', + user_id: UUID, amount: Decimal ) -> InvoiceItem | None: """ Includes a donation for the given user and period. @@ -244,7 +246,7 @@ def include_donation( paid=False ) - def exclude_donation(self, user_id: 'UUID') -> bool | None: + def exclude_donation(self, user_id: UUID) -> bool | None: invoice = ( self.invoices.query() .outerjoin(User) @@ -283,7 +285,7 @@ def create_invoices( # delete all existing invoices invoice_ids = invoices.query().with_entities(Invoice.id).subquery() - def delete_queries() -> 'Iterator[Query[Any]]': + def delete_queries() -> Iterator[Query[Any]]: yield session.query(InvoiceReference).filter( InvoiceReference.invoice_id.in_(invoice_ids)) @@ -329,14 +331,14 @@ class BookingInvoiceBridge: """ - attendees: dict['UUID', tuple[str, str]] - processed_attendees: set['UUID'] - billed_attendees: set['UUID'] + attendees: dict[UUID, tuple[str, str]] + processed_attendees: set[UUID] + billed_attendees: set[UUID] def __init__( self, - session: 'Session', - period: 'Period | PeriodMeta' + session: Session, + period: Period | PeriodMeta ) -> None: # tracks attendees which had at least one booking added through the # bridge (even if said booking was free) diff --git a/src/onegov/feriennet/collections/match.py b/src/onegov/feriennet/collections/match.py index dfef7de1e5..51b161e0e1 100644 --- a/src/onegov/feriennet/collections/match.py +++ b/src/onegov/feriennet/collections/match.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import Booking, Attendee, Occasion from onegov.core.utils import toggle from onegov.core.orm import as_selectable_from_path @@ -19,7 +21,7 @@ from uuid import UUID class OccasionByStateRow(NamedTuple): - state: 'OccasionState | None' + state: OccasionState | None occasion_id: UUID title: str start: datetime @@ -33,7 +35,7 @@ class OccasionByStateRow(NamedTuple): total_bookings: int period_id: UUID -OccasionState: 'TypeAlias' = Literal[ +OccasionState: TypeAlias = Literal[ 'cancelled', 'overfull', 'empty', @@ -47,22 +49,22 @@ class MatchCollection: def __init__( self, - session: 'Session', - period: 'Period | PeriodMeta', - states: 'Collection[OccasionState] | None' = None + session: Session, + period: Period | PeriodMeta, + states: Collection[OccasionState] | None = None ) -> None: self.session = session self.period = period self.states = set(states) if states else set() @property - def period_id(self) -> 'UUID': + def period_id(self) -> UUID: return self.period.id - def for_period(self, period: 'Period | PeriodMeta') -> 'Self': + def for_period(self, period: Period | PeriodMeta) -> Self: return self.__class__(self.session, period) - def for_filter(self, state: OccasionState | None = None) -> 'Self': + def for_filter(self, state: OccasionState | None = None) -> Self: toggled = toggle(self.states, state) return self.__class__(self.session, self.period, toggled) @@ -81,7 +83,7 @@ def happiness(self) -> float: return 0 @property - def occasions_by_state(self) -> 'Alias': + def occasions_by_state(self) -> Alias: return as_selectable_from_path( module_path('onegov.feriennet', 'queries/occasions_by_state.sql')) @@ -108,14 +110,14 @@ def operability(self) -> float: return sum(bits) / len(bits) - def include_in_output(self, occasion: 'OccasionByStateRow') -> bool: + def include_in_output(self, occasion: OccasionByStateRow) -> bool: if not self.states: return True return occasion.state in self.states @property - def occasions(self) -> 'Query[OccasionByStateRow]': + def occasions(self) -> Query[OccasionByStateRow]: columns = self.occasions_by_state.c query = select(columns) diff --git a/src/onegov/feriennet/collections/notification_template.py b/src/onegov/feriennet/collections/notification_template.py index 9ab22e08f8..e8dc0ae45b 100644 --- a/src/onegov/feriennet/collections/notification_template.py +++ b/src/onegov/feriennet/collections/notification_template.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.collection import GenericCollection @@ -12,7 +14,7 @@ class NotificationTemplateCollection( ): @cached_property - def model_class(self) -> type['NotificationTemplate']: + def model_class(self) -> type[NotificationTemplate]: # XXX circular import from onegov.feriennet.models import NotificationTemplate diff --git a/src/onegov/feriennet/collections/occasion_attendees.py b/src/onegov/feriennet/collections/occasion_attendees.py index 4de39d46bb..f8417d5edb 100644 --- a/src/onegov/feriennet/collections/occasion_attendees.py +++ b/src/onegov/feriennet/collections/occasion_attendees.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict, Counter from onegov.activity import Activity, Attendee, Occasion, OccasionCollection from onegov.user import User @@ -18,7 +20,7 @@ class ContactInfo(TypedDict): class OccasionAttendee(NamedTuple): attendee: Attendee - info: 'ContactInfo' + info: ContactInfo group_code: str | None @@ -26,8 +28,8 @@ class OccasionAttendeeCollection(OccasionCollection): def __init__( self, - session: 'Session', - period: 'Period | PeriodMeta', + session: Session, + period: Period | PeriodMeta, activity: Activity, username: str | None = None ) -> None: @@ -37,18 +39,18 @@ def __init__( self.activity = activity @property - def period_id(self) -> 'UUID': + def period_id(self) -> UUID: return self.period.id @property def activity_name(self) -> str: return self.activity.name - def for_period(self, period: 'Period | PeriodMeta') -> 'Self': + def for_period(self, period: Period | PeriodMeta) -> Self: return self.__class__( self.session, period, self.activity, self.username) - def query(self) -> 'Query[Occasion]': + def query(self) -> Query[Occasion]: q = super().query() q = q.join(Occasion.activity) diff --git a/src/onegov/feriennet/const.py b/src/onegov/feriennet/const.py index 53a52a91c9..c92b30b3fc 100644 --- a/src/onegov/feriennet/const.py +++ b/src/onegov/feriennet/const.py @@ -1,5 +1,7 @@ #: Describes the states which are visible to the given role (not taking # ownership in account!) +from __future__ import annotations + VISIBLE_ACTIVITY_STATES = { 'admin': ( 'preview', diff --git a/src/onegov/feriennet/converters.py b/src/onegov/feriennet/converters.py index 7cb47a18cb..b8ef6c62d4 100644 --- a/src/onegov/feriennet/converters.py +++ b/src/onegov/feriennet/converters.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import morepath import re diff --git a/src/onegov/feriennet/custom.py b/src/onegov/feriennet/custom.py index 8caf96e606..6b03629a00 100644 --- a/src/onegov/feriennet/custom.py +++ b/src/onegov/feriennet/custom.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import BookingCollection from onegov.activity import PeriodCollection from onegov.activity import VolunteerCollection @@ -20,7 +22,7 @@ @FeriennetApp.template_variables() -def get_template_variables(request: 'FeriennetRequest') -> 'RenderData': +def get_template_variables(request: FeriennetRequest) -> RenderData: return { 'global_tools': tuple(get_global_tools(request)), 'top_navigation': tuple(get_top_navigation(request)) @@ -28,8 +30,8 @@ def get_template_variables(request: 'FeriennetRequest') -> 'RenderData': def get_global_tools( - request: 'FeriennetRequest' -) -> 'Iterator[Link | LinkGroup]': + request: FeriennetRequest +) -> Iterator[Link | LinkGroup]: yield from get_base_tools(request) yield from get_personal_tools(request) yield from get_admin_tools(request) @@ -45,8 +47,8 @@ def get_global_tools( def get_admin_tools( - request: 'FeriennetRequest' -) -> 'Iterator[Link | LinkGroup]': + request: FeriennetRequest +) -> Iterator[Link | LinkGroup]: if request.is_organiser: period = request.app.active_period periods = request.app.periods @@ -138,8 +140,8 @@ def get_admin_tools( def get_personal_tools( - request: 'FeriennetRequest' -) -> 'Iterator[Link | LinkGroup]': + request: FeriennetRequest +) -> Iterator[Link | LinkGroup]: # for logged-in users show the number of open bookings if request.is_logged_in: session = request.session @@ -215,7 +217,7 @@ def get_personal_tools( ) -def get_top_navigation(request: 'FeriennetRequest') -> 'Iterator[Link]': +def get_top_navigation(request: FeriennetRequest) -> Iterator[Link]: # inject an activites link in front of all top navigation links yield Link( text=_('Activities'), diff --git a/src/onegov/feriennet/exports/base.py b/src/onegov/feriennet/exports/base.py index d5a670c81e..6a02ea65ce 100644 --- a/src/onegov/feriennet/exports/base.py +++ b/src/onegov/feriennet/exports/base.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re import sedate @@ -98,8 +100,8 @@ class FeriennetExport(Export): def activity_fields( self, - activity: 'Activity' - ) -> 'Iterator[tuple[str, Any]]': + activity: Activity + ) -> Iterator[tuple[str, Any]]: yield _('Activity Title'), activity.title yield _('Activity Lead'), activity.lead @@ -111,8 +113,8 @@ def activity_fields( def booking_fields( self, - booking: 'Booking' - ) -> 'Iterator[tuple[str, Any]]': + booking: Booking + ) -> Iterator[tuple[str, Any]]: yield _('Booking State'), BOOKING_STATES[booking.state] yield _('Booking Priority'), booking.priority @@ -123,8 +125,8 @@ def booking_fields( def attendee_fields( self, - attendee: 'Attendee' - ) -> 'Iterator[tuple[str, Any]]': + attendee: Attendee + ) -> Iterator[tuple[str, Any]]: first_name, last_name = decode_name(attendee.name) @@ -137,8 +139,8 @@ def attendee_fields( def occasion_fields( self, - occasion: 'Occasion' - ) -> 'Iterator[tuple[str, Any]]': + occasion: Occasion + ) -> Iterator[tuple[str, Any]]: dates = [ (d.localized_start, d.localized_end) @@ -159,8 +161,8 @@ def occasion_fields( def occasion_need_fields( self, - need: 'OccasionNeed' - ) -> 'Iterator[tuple[str, Any]]': + need: OccasionNeed + ) -> Iterator[tuple[str, Any]]: yield _('Need Number'), '{} - {}'.format( need.number.lower, need.number.upper - 1) @@ -169,12 +171,12 @@ def occasion_need_fields( def activity_tags( self, - tags: 'Iterable[str] | None' - ) -> 'Iterator[tuple[str, Any]]': + tags: Iterable[str] | None + ) -> Iterator[tuple[str, Any]]: yield _('Activity Tags'), '\n'.join(sorted(tags or [])) - def user_fields(self, user: 'User') -> 'Iterator[tuple[str, Any]]': + def user_fields(self, user: User) -> Iterator[tuple[str, Any]]: user_data = user.data or {} salutation = user_data.get('salutation') first_name, last_name = decode_name(user.realname) @@ -209,8 +211,8 @@ def user_fields(self, user: 'User') -> 'Iterator[tuple[str, Any]]': def invoice_item_fields( self, - item: 'InvoiceItem' - ) -> 'Iterator[tuple[str, Any]]': + item: InvoiceItem + ) -> Iterator[tuple[str, Any]]: yield _('Invoice Item Group'), item.group yield _('Invoice Item Text'), item.text @@ -228,8 +230,8 @@ def invoice_item_fields( def invoice_attendee_fields( self, - attendee: 'Attendee' - ) -> 'Iterator[tuple[str, Any]]': + attendee: Attendee + ) -> Iterator[tuple[str, Any]]: yield _('Attendee Address'), attendee.address if attendee else '' yield _('Attendee Zipcode'), attendee.zip_code if attendee else '' @@ -239,8 +241,8 @@ def invoice_attendee_fields( def organiser_fields( self, - organiser: 'User' - ) -> 'Iterator[tuple[str, Any]]': + organiser: User + ) -> Iterator[tuple[str, Any]]: user_data = organiser.data or {} first_name, last_name = decode_name(organiser.realname) @@ -262,8 +264,8 @@ def organiser_fields( def volunteer_fields( self, - volunteer: 'Volunteer' - ) -> 'Iterator[tuple[str, Any]]': + volunteer: Volunteer + ) -> Iterator[tuple[str, Any]]: need = volunteer.need occasion = need.occasion diff --git a/src/onegov/feriennet/exports/booking.py b/src/onegov/feriennet/exports/booking.py index d25ed694e0..d7e58cb171 100644 --- a/src/onegov/feriennet/exports/booking.py +++ b/src/onegov/feriennet/exports/booking.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import Activity, Attendee, Booking, Occasion from onegov.core.security import Secret from onegov.feriennet import FeriennetApp, _ @@ -29,8 +31,8 @@ class BookingExport(FeriennetExport): def run( self, form: PeriodExportForm, # type:ignore[override] - session: 'Session' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session + ) -> Iterator[Iterator[tuple[str, Any]]]: assert form.selected_period is not None @@ -41,7 +43,7 @@ def run( return self.rows(session, form.selected_period) - def query(self, session: 'Session', period: 'Period') -> 'Query[Booking]': + def query(self, session: Session, period: Period) -> Query[Booking]: q = session.query(Booking) q = q.filter(Booking.period_id == period.id) @@ -68,18 +70,18 @@ def query(self, session: 'Session', period: 'Period') -> 'Query[Booking]': def rows( self, - session: 'Session', - period: 'Period' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session, + period: Period + ) -> Iterator[Iterator[tuple[str, Any]]]: for booking in self.query(session, period): yield ((k, v) for k, v in self.fields(period, booking)) def fields( self, - period: 'Period', + period: Period, booking: Booking - ) -> 'Iterator[tuple[str, Any]]': + ) -> Iterator[tuple[str, Any]]: yield from self.booking_fields(booking) yield from self.activity_fields(booking.occasion.activity) diff --git a/src/onegov/feriennet/exports/const.py b/src/onegov/feriennet/exports/const.py index 86855e9022..3b8f6ac3a6 100644 --- a/src/onegov/feriennet/exports/const.py +++ b/src/onegov/feriennet/exports/const.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.feriennet import _ diff --git a/src/onegov/feriennet/exports/invoiceitem.py b/src/onegov/feriennet/exports/invoiceitem.py index f499906954..c0957a1155 100644 --- a/src/onegov/feriennet/exports/invoiceitem.py +++ b/src/onegov/feriennet/exports/invoiceitem.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import ( Invoice, InvoiceItem, Activity, Occasion, Attendee) from onegov.core.security import Secret @@ -29,25 +31,25 @@ class InvoiceItemExport(FeriennetExport): def run( self, form: PeriodExportForm, # type:ignore[override] - session: 'Session' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session + ) -> Iterator[Iterator[tuple[str, Any]]]: assert form.selected_period is not None return self.rows(session, form.selected_period) def rows( self, - session: 'Session', - period: 'Period' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session, + period: Period + ) -> Iterator[Iterator[tuple[str, Any]]]: for item, tags, attendee in self.query(session, period): yield ((k, v) for k, v in self.fields(item, tags, attendee)) def query( self, - session: 'Session', - period: 'Period' - ) -> 'Query[tuple[InvoiceItem, list[str] | None, Attendee]]': + session: Session, + period: Period + ) -> Query[tuple[InvoiceItem, list[str] | None, Attendee]]: # There might be activities with same title from other periods # resulting in double entries of invoice items @@ -88,7 +90,7 @@ def fields( item: InvoiceItem, tags: list[str] | None, attendee: Attendee - ) -> 'Iterator[tuple[str, Any]]': + ) -> Iterator[tuple[str, Any]]: yield from self.invoice_item_fields(item) yield from self.user_fields(item.invoice.user) diff --git a/src/onegov/feriennet/exports/occasion.py b/src/onegov/feriennet/exports/occasion.py index 98544f06d3..9fd4b71dc1 100644 --- a/src/onegov/feriennet/exports/occasion.py +++ b/src/onegov/feriennet/exports/occasion.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import Activity, Occasion, OccasionNeed from onegov.core.security import Secret from onegov.feriennet import FeriennetApp, _ @@ -25,13 +27,13 @@ class OccasionExport(FeriennetExport): def run( self, form: PeriodExportForm, # type:ignore[override] - session: 'Session' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session + ) -> Iterator[Iterator[tuple[str, Any]]]: assert form.selected_period is not None return self.rows(session, form.selected_period) - def query(self, session: 'Session', period: 'Period') -> 'Query[Occasion]': + def query(self, session: Session, period: Period) -> Query[Occasion]: q = session.query(Occasion) q = q.filter(Occasion.period_id == period.id) q = q.options(joinedload(Occasion.activity).joinedload(Activity.user)) @@ -43,14 +45,14 @@ def query(self, session: 'Session', period: 'Period') -> 'Query[Occasion]': def rows( self, - session: 'Session', - period: 'Period' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session, + period: Period + ) -> Iterator[Iterator[tuple[str, Any]]]: for occasion in self.query(session, period): yield ((k, v) for k, v in self.fields(occasion)) - def fields(self, occasion: Occasion) -> 'Iterator[tuple[str, Any]]': + def fields(self, occasion: Occasion) -> Iterator[tuple[str, Any]]: yield from self.activity_fields(occasion.activity) yield from self.occasion_fields(occasion) yield from self.user_fields(occasion.activity.user) @@ -68,17 +70,17 @@ class OccasionNeedExport(FeriennetExport): def run( self, form: PeriodExportForm, # type:ignore[override] - session: 'Session' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session + ) -> Iterator[Iterator[tuple[str, Any]]]: assert form.selected_period is not None return self.rows(session, form.selected_period) def query( self, - session: 'Session', - period: 'Period' - ) -> 'Query[OccasionNeed]': + session: Session, + period: Period + ) -> Query[OccasionNeed]: q = session.query(OccasionNeed) q = q.filter(OccasionNeed.occasion_id.in_( @@ -102,14 +104,14 @@ def query( def rows( self, - session: 'Session', - period: 'Period' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session, + period: Period + ) -> Iterator[Iterator[tuple[str, Any]]]: for need in self.query(session, period): yield ((k, v) for k, v in self.fields(need)) - def fields(self, need: OccasionNeed) -> 'Iterator[tuple[str, Any]]': + def fields(self, need: OccasionNeed) -> Iterator[tuple[str, Any]]: yield from self.activity_fields(need.occasion.activity) yield from self.occasion_fields(need.occasion) yield from self.occasion_need_fields(need) diff --git a/src/onegov/feriennet/exports/unlucky.py b/src/onegov/feriennet/exports/unlucky.py index 8574ff6400..291039d6ea 100644 --- a/src/onegov/feriennet/exports/unlucky.py +++ b/src/onegov/feriennet/exports/unlucky.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import AttendeeCollection, Attendee, Booking from onegov.core.security import Secret from onegov.feriennet import FeriennetApp, _ @@ -27,17 +29,17 @@ class UnluckyExport(FeriennetExport): def run( self, form: PeriodSelectForm, # type:ignore[override] - session: 'Session' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session + ) -> Iterator[Iterator[tuple[str, Any]]]: assert form.selected_period is not None return self.rows(session, form.selected_period) def query( self, - session: 'Session', - period: 'Period | PeriodMeta' - ) -> 'Query[Attendee]': + session: Session, + period: Period | PeriodMeta + ) -> Query[Attendee]: with_any_bookings = session.query(Booking.attendee_id).filter( Booking.period_id == period.id).subquery() @@ -54,13 +56,13 @@ def query( def rows( self, - session: 'Session', - period: 'Period | PeriodMeta' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session, + period: Period | PeriodMeta + ) -> Iterator[Iterator[tuple[str, Any]]]: for user in self.query(session, period): yield ((k, v) for k, v in self.fields(user)) - def fields(self, attendee: Attendee) -> 'Iterator[tuple[str, Any]]': + def fields(self, attendee: Attendee) -> Iterator[tuple[str, Any]]: yield from self.attendee_fields(attendee) yield from self.user_fields(attendee.user) diff --git a/src/onegov/feriennet/exports/user.py b/src/onegov/feriennet/exports/user.py index a967cf41dd..9d842dd9a5 100644 --- a/src/onegov/feriennet/exports/user.py +++ b/src/onegov/feriennet/exports/user.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Secret from onegov.feriennet import FeriennetApp, _ from onegov.feriennet.exports.base import FeriennetExport @@ -23,21 +25,21 @@ class UserExport(FeriennetExport): def run( self, form: ExportForm, # type:ignore[override] - session: 'Session' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session + ) -> Iterator[Iterator[tuple[str, Any]]]: return self.rows(session) - def query(self, session: 'Session') -> 'Query[User]': + def query(self, session: Session) -> Query[User]: return UserCollection(session).query().order_by(User.username) def rows( self, - session: 'Session' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session + ) -> Iterator[Iterator[tuple[str, Any]]]: for user in self.query(session): yield ((k, v) for k, v in self.fields(user)) - def fields(self, user: User) -> 'Iterator[tuple[str, Any]]': + def fields(self, user: User) -> Iterator[tuple[str, Any]]: yield from self.user_fields(user) diff --git a/src/onegov/feriennet/exports/volunteers.py b/src/onegov/feriennet/exports/volunteers.py index 0386e665b0..aaaa53ec27 100644 --- a/src/onegov/feriennet/exports/volunteers.py +++ b/src/onegov/feriennet/exports/volunteers.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import Occasion, OccasionNeed from onegov.core.security import Secret from onegov.feriennet import FeriennetApp, _ @@ -25,17 +27,17 @@ class VolunteerExport(FeriennetExport): def run( self, form: PeriodExportForm, # type:ignore[override] - session: 'Session' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session + ) -> Iterator[Iterator[tuple[str, Any]]]: assert form.selected_period is not None return self.rows(session, form.selected_period) def query( self, - session: 'Session', - period: 'Period' - ) -> 'Query[OccasionNeed]': + session: Session, + period: Period + ) -> Query[OccasionNeed]: q = session.query(OccasionNeed) q = q.filter(OccasionNeed.occasion_id.in_( @@ -59,14 +61,14 @@ def query( def rows( self, - session: 'Session', - period: 'Period' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session, + period: Period + ) -> Iterator[Iterator[tuple[str, Any]]]: for need in self.query(session, period): for volunteer in need.volunteers: yield ((k, v) for k, v in self.fields(volunteer)) - def fields(self, volunteer: 'Volunteer') -> 'Iterator[tuple[str, Any]]': + def fields(self, volunteer: Volunteer) -> Iterator[tuple[str, Any]]: yield from self.volunteer_fields(volunteer) diff --git a/src/onegov/feriennet/forms/__init__.py b/src/onegov/feriennet/forms/__init__.py index dbd82c871d..f62781d3ed 100644 --- a/src/onegov/feriennet/forms/__init__.py +++ b/src/onegov/feriennet/forms/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.feriennet.forms.activity import VacationActivityForm from onegov.feriennet.forms.attendee import AttendeeForm from onegov.feriennet.forms.attendee import AttendeeLimitForm diff --git a/src/onegov/feriennet/forms/activity.py b/src/onegov/feriennet/forms/activity.py index 1084222068..c6b4d09b9b 100644 --- a/src/onegov/feriennet/forms/activity.py +++ b/src/onegov/feriennet/forms/activity.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import normalize_for_url from onegov.feriennet import _ from onegov.form import Form @@ -57,7 +59,7 @@ class VacationActivityForm(Form): - request: 'FeriennetRequest' + request: FeriennetRequest title = StringField( label=_('Title'), @@ -90,7 +92,7 @@ class VacationActivityForm(Form): ) @property - def username_choices(self) -> list['_Choice']: + def username_choices(self) -> list[_Choice]: assert self.request.is_admin # safety net users = ( @@ -99,10 +101,10 @@ def username_choices(self) -> list['_Choice']: .with_entities(User.username, User.title) ) - def choice(row: tuple[str, str]) -> '_Choice': + def choice(row: tuple[str, str]) -> _Choice: return row[0], row[1] - def by_title(choice: '_Choice') -> str: + def by_title(choice: _Choice) -> str: return normalize_for_url(choice[1]) return sorted((choice(r) for r in users), key=by_title) diff --git a/src/onegov/feriennet/forms/attendee.py b/src/onegov/feriennet/forms/attendee.py index 7ed3506e31..bb6ec2c56c 100644 --- a/src/onegov/feriennet/forms/attendee.py +++ b/src/onegov/feriennet/forms/attendee.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.activity import Attendee, AttendeeCollection from onegov.activity import Booking, BookingCollection, Occasion @@ -29,7 +31,7 @@ class AttendeeBase(Form): - request: 'FeriennetRequest' + request: FeriennetRequest if TYPE_CHECKING: first_name: StringField @@ -267,7 +269,7 @@ def show_political_municipality(self) -> bool | None: return self.request.app.org.meta.get('show_political_municipality') @cached_property - def user(self) -> 'User | None': + def user(self) -> User | None: if not self.username: return None users = UserCollection(self.request.session) diff --git a/src/onegov/feriennet/forms/bank_statement.py b/src/onegov/feriennet/forms/bank_statement.py index 43290babd9..542e9dcccb 100644 --- a/src/onegov/feriennet/forms/bank_statement.py +++ b/src/onegov/feriennet/forms/bank_statement.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import Period, PeriodCollection from onegov.feriennet import _ from onegov.form import Form @@ -33,7 +35,7 @@ class BankStatementImportForm(Form): ) @property - def period_choices(self) -> list['_Choice']: + def period_choices(self) -> list[_Choice]: periods = PeriodCollection(self.request.session) q = periods.query() @@ -43,7 +45,7 @@ def period_choices(self) -> list['_Choice']: # NOTE: Technically not quite correct, it's a Row with two named # fields. But this is close enough for our purposes and is # quicker than defining a matching NamedTuple. - def choice(row: Period) -> '_Choice': + def choice(row: Period) -> _Choice: return row.id.hex, row.title return [choice(p) for p in q] diff --git a/src/onegov/feriennet/forms/billing.py b/src/onegov/feriennet/forms/billing.py index aa97bd0918..ea5461a121 100644 --- a/src/onegov/feriennet/forms/billing.py +++ b/src/onegov/feriennet/forms/billing.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.activity import Invoice from onegov.feriennet import _ @@ -91,7 +93,7 @@ class ManualBookingForm(Form): ) @property - def amount(self) -> 'Decimal': + def amount(self) -> Decimal: if self.kind.data == 'discount': assert self.discount.data is not None return -self.discount.data @@ -106,7 +108,7 @@ def text(self) -> str | None: return self.booking_text.data @property - def available_usernames(self) -> 'Query[tuple[str, str]]': + def available_usernames(self) -> Query[tuple[str, str]]: return ( self.usercollection.query() .with_entities(User.username, User.realname) diff --git a/src/onegov/feriennet/forms/donation.py b/src/onegov/feriennet/forms/donation.py index 1454cec5c6..4e4c54b333 100644 --- a/src/onegov/feriennet/forms/donation.py +++ b/src/onegov/feriennet/forms/donation.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.feriennet import _ from onegov.form import Form from onegov.feriennet.const import DEFAULT_DONATION_AMOUNTS @@ -13,7 +15,7 @@ class DonationForm(Form): - request: 'FeriennetRequest' + request: FeriennetRequest amount = SelectField( label=_('My donation'), diff --git a/src/onegov/feriennet/forms/match.py b/src/onegov/feriennet/forms/match.py index 3c4cd0d5e7..88c3dc039f 100644 --- a/src/onegov/feriennet/forms/match.py +++ b/src/onegov/feriennet/forms/match.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity.matching.score import PreferAdminChildren from onegov.activity.matching.score import PreferOrganiserChildren from onegov.activity.matching.score import PreferGroups @@ -39,7 +41,7 @@ class MatchForm(Form): depends_on=('confirm', 'yes') ) - def scoring(self, session: 'Session') -> Scoring: + def scoring(self, session: Session) -> Scoring: scoring = Scoring() # always prefer groups diff --git a/src/onegov/feriennet/forms/notification_template.py b/src/onegov/feriennet/forms/notification_template.py index a2b2446bd3..bb5124f5e9 100644 --- a/src/onegov/feriennet/forms/notification_template.py +++ b/src/onegov/feriennet/forms/notification_template.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from markupsafe import Markup, escape @@ -58,7 +60,7 @@ def validate_subject(self, field: StringField) -> None: class NotificationTemplateSendForm(Form): - request: 'FeriennetRequest' + request: FeriennetRequest send_to = RadioField( label=_('Send to'), @@ -127,7 +129,7 @@ def on_request(self) -> None: self.occasion.choices = list(self.occasion_choices) @cached_property - def period(self) -> 'PeriodMeta': + def period(self) -> PeriodMeta: for period in self.request.app.periods: if period.id == self.model.period_id: return period @@ -179,7 +181,7 @@ def recipients_pool(self) -> set[str]: return {u.username for u in users.with_entities(User.username)} - def recipients_by_role(self, roles: 'Collection[str]') -> set[str]: + def recipients_by_role(self, roles: Collection[str]) -> set[str]: if not roles: return set() @@ -240,8 +242,8 @@ def recipients_by_occasion_query( # if we wanted to be a little bit more rigorous we could # use `coerce` on `MultiCheckboxField` to ensure we're # passing in `UUID`s, rather than `str`s. - occasions: 'Collection[str]' - ) -> 'Query[Booking]': + occasions: Collection[str] + ) -> Query[Booking]: bookings = BookingCollection(self.request.session) q = bookings.query().order_by(None) @@ -264,7 +266,7 @@ def recipients_by_occasion_query( def recipients_by_occasion( self, - occasions: 'Collection[str]', + occasions: Collection[str], include_organisers: bool = True ) -> set[str]: @@ -286,7 +288,7 @@ def recipients_by_occasion( return attendees | organisers @property - def occasion_choices(self) -> 'Iterator[tuple[str, Markup]]': + def occasion_choices(self) -> Iterator[tuple[str, Markup]]: layout = DefaultLayout(self.model, self.request) stmt = as_selectable_from_path( diff --git a/src/onegov/feriennet/forms/occasion.py b/src/onegov/feriennet/forms/occasion.py index af62831e2e..7d67309af2 100644 --- a/src/onegov/feriennet/forms/occasion.py +++ b/src/onegov/feriennet/forms/occasion.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import isodate from decimal import Decimal @@ -29,7 +31,7 @@ class OccasionForm(Form): - request: 'FeriennetRequest' + request: FeriennetRequest timezone = 'Europe/Zurich' @@ -173,8 +175,8 @@ def selected_period(self) -> Period | None: self.period_id.data) class DateRange(NamedTuple): - start: 'datetime' - end: 'datetime' + start: datetime + end: datetime @cached_property def parsed_dates(self) -> list[DateRange]: @@ -331,12 +333,12 @@ def ensure_max_spots_higher_than_accepted_bookings(self) -> bool | None: def dates_to_json( self, - dates: 'Sequence[DateRange | OccasionDate] | None' = None + dates: Sequence[DateRange | OccasionDate] | None = None ) -> str: dates = dates or [] - def as_json_date(date: 'datetime') -> str: + def as_json_date(date: datetime) -> str: return ( to_timezone(date, self.timezone) .replace(tzinfo=None).isoformat() diff --git a/src/onegov/feriennet/forms/occasion_need.py b/src/onegov/feriennet/forms/occasion_need.py index be398af6d3..2936cfe8ed 100644 --- a/src/onegov/feriennet/forms/occasion_need.py +++ b/src/onegov/feriennet/forms/occasion_need.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import OccasionNeed from onegov.activity.types import BoundedIntegerRange from onegov.feriennet import _ diff --git a/src/onegov/feriennet/forms/period.py b/src/onegov/feriennet/forms/period.py index 3e6c007ec7..4acbeb6f2c 100644 --- a/src/onegov/feriennet/forms/period.py +++ b/src/onegov/feriennet/forms/period.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from datetime import date, datetime from onegov.activity import Activity, Period, Occasion, OccasionDate @@ -27,7 +29,7 @@ class PeriodSelectForm(Form): - request: 'FeriennetRequest' + request: FeriennetRequest period = SelectField( label=_('Period'), @@ -35,7 +37,7 @@ class PeriodSelectForm(Form): default='0xdeadbeef') @property - def period_choices(self) -> list['_Choice']: + def period_choices(self) -> list[_Choice]: q = PeriodCollection(self.request.session).query() q = q.with_entities(Period.id, Period.title) q = q.order_by(Period.execution_start) @@ -48,7 +50,7 @@ def selected_period(self) -> Period | None: self.period.data) @property - def active_period(self) -> 'PeriodMeta | None': + def active_period(self) -> PeriodMeta | None: return self.request.app.active_period def on_request(self) -> None: diff --git a/src/onegov/feriennet/forms/userprofile.py b/src/onegov/feriennet/forms/userprofile.py index 886c3dfcec..655a82f5ce 100644 --- a/src/onegov/feriennet/forms/userprofile.py +++ b/src/onegov/feriennet/forms/userprofile.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import string from onegov.feriennet import _ @@ -20,7 +22,7 @@ class UserProfileForm(Form): """ Custom userprofile form for feriennet """ - request: 'FeriennetRequest' + request: FeriennetRequest extra_fields = ( 'salutation', @@ -208,7 +210,7 @@ def should_skip_key(self, key: str) -> bool: return False - def populate_obj(self, model: 'User') -> None: # type:ignore[override] + def populate_obj(self, model: User) -> None: # type:ignore[override] super().populate_obj(model) if model: @@ -226,7 +228,7 @@ def populate_obj(self, model: 'User') -> None: # type:ignore[override] if isinstance(model.data[key], str): model.data[key] = model.data[key].strip() - def process_obj(self, model: 'User') -> None: # type:ignore[override] + def process_obj(self, model: User) -> None: # type:ignore[override] super().process_obj(model) if model: diff --git a/src/onegov/feriennet/forms/volunteer.py b/src/onegov/feriennet/forms/volunteer.py index 02451cf9aa..0dd34a777f 100644 --- a/src/onegov/feriennet/forms/volunteer.py +++ b/src/onegov/feriennet/forms/volunteer.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.feriennet import _ from onegov.form import Form from wtforms.fields import DateField diff --git a/src/onegov/feriennet/homepage_widgets.py b/src/onegov/feriennet/homepage_widgets.py index d2ba6b8380..b6bc813387 100644 --- a/src/onegov/feriennet/homepage_widgets.py +++ b/src/onegov/feriennet/homepage_widgets.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.feriennet import FeriennetApp, _ @@ -27,7 +29,7 @@ class RegistrationWidget: """ - def get_variables(self, layout: 'DefaultLayout') -> 'RenderData': + def get_variables(self, layout: DefaultLayout) -> RenderData: return { 'register_text': _('Register a new account'), 'login_text': _('Go to Login'), diff --git a/src/onegov/feriennet/initial_content.py b/src/onegov/feriennet/initial_content.py index 550bd84331..42841c2c38 100644 --- a/src/onegov/feriennet/initial_content.py +++ b/src/onegov/feriennet/initial_content.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import textwrap from onegov.core.utils import module_path @@ -12,7 +14,7 @@ def create_new_organisation( - app: 'FeriennetApp', + app: FeriennetApp, name: str, create_files: bool = True, path: str | None = None, diff --git a/src/onegov/feriennet/layout.py b/src/onegov/feriennet/layout.py index 11635f515a..7895462027 100644 --- a/src/onegov/feriennet/layout.py +++ b/src/onegov/feriennet/layout.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.activity import Activity, PeriodCollection, Occasion @@ -37,8 +39,8 @@ class DefaultLayout(BaseLayout): - app: 'FeriennetApp' - request: 'FeriennetRequest' + app: FeriennetApp + request: FeriennetRequest @property def is_owner(self) -> bool: @@ -90,10 +92,10 @@ def offer_again_link(self, activity: VacationActivity, title: str) -> Link: attrs={'class': 'offer-again'} ) - def linkify(self, text: str | None) -> 'Markup': # type:ignore[override] + def linkify(self, text: str | None) -> Markup: # type:ignore[override] return linkify(text) - def paragraphify(self, text: str) -> 'Markup': + def paragraphify(self, text: str) -> Markup: return paragraphify(text) @@ -105,7 +107,7 @@ class VacationActivityCollectionLayout(DefaultLayout): def __init__( self, model: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: ... @cached_property @@ -117,7 +119,7 @@ def breadcrumbs(self) -> list[Link]: ] @property - def organiser_links(self) -> 'Iterator[Link | LinkGroup]': + def organiser_links(self) -> Iterator[Link | LinkGroup]: if self.app.active_period: yield Link( text=_('Submit Activity'), @@ -166,8 +168,8 @@ class BookingCollectionLayout(DefaultLayout): def __init__( self, model: BookingCollection, - request: 'FeriennetRequest', - user: 'User | None' = None + request: FeriennetRequest, + user: User | None = None ) -> None: super().__init__(model, request) if user is None: @@ -177,9 +179,9 @@ def __init__( def rega_link( self, - attendee: 'Attendee | None', - period: 'Period | None', - grouped_bookings: dict['Attendee', dict[str, list['Booking']]] + attendee: Attendee | None, + period: Period | None, + grouped_bookings: dict[Attendee, dict[str, list[Booking]]] ) -> str | None: if not (period or attendee or grouped_bookings): @@ -248,7 +250,7 @@ class VacationActivityFormLayout(DefaultLayout): def __init__( self, model: VacationActivity | VacationActivityCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, title: str ) -> None: @@ -277,7 +279,7 @@ class OccasionFormLayout(DefaultLayout): def __init__( self, model: Activity, - request: 'FeriennetRequest', + request: FeriennetRequest, title: str ) -> None: @@ -308,7 +310,7 @@ class VacationActivityLayout(DefaultLayout): def __init__( self, model: VacationActivity, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: ... @cached_property @@ -321,11 +323,11 @@ def breadcrumbs(self) -> list[Link]: ] @cached_property - def latest_request(self) -> 'PublicationRequest | None': + def latest_request(self) -> PublicationRequest | None: return self.model.latest_request @cached_property - def ticket(self) -> 'Ticket | None': + def ticket(self) -> Ticket | None: if self.latest_request: tickets = TicketCollection(self.request.session) return tickets.by_handler_id(self.latest_request.id.hex) @@ -508,12 +510,12 @@ def editbar_links(self) -> list[Link | LinkGroup]: class PeriodFormLayout(DefaultLayout): - model: 'Period | PeriodCollection' + model: Period | PeriodCollection def __init__( self, - model: 'Period | PeriodCollection', - request: 'FeriennetRequest', + model: Period | PeriodCollection, + request: FeriennetRequest, title: str ) -> None: super().__init__(model, request) @@ -561,7 +563,7 @@ class BillingCollectionLayout(DefaultLayout): def __init__( self, model: BillingCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: ... class FamilyRow(NamedTuple): @@ -571,7 +573,7 @@ class FamilyRow(NamedTuple): has_online_payments: bool @property - def families(self) -> 'Iterator[FamilyRow]': + def families(self) -> Iterator[FamilyRow]: yield from self.app.session().execute(""" SELECT text @@ -594,7 +596,7 @@ def families(self) -> 'Iterator[FamilyRow]': """) @property - def family_removal_links(self) -> 'Iterator[Link]': + def family_removal_links(self) -> Iterator[Link]: attrs = { 'class': ('remove-manual', 'extend-to-family') } @@ -699,7 +701,7 @@ class OnlinePaymentsLayout(DefaultLayout): def __init__( self, model: Any, - request: 'FeriennetRequest', + request: FeriennetRequest, title: str ) -> None: @@ -784,7 +786,7 @@ class InvoiceLayout(DefaultLayout): def __init__( self, model: Any, - request: 'FeriennetRequest', + request: FeriennetRequest, title: str ) -> None: super().__init__(model, request) @@ -802,8 +804,8 @@ class DonationLayout(DefaultLayout): def __init__( self, - model: 'InvoiceCollection', - request: 'FeriennetRequest', + model: InvoiceCollection, + request: FeriennetRequest, title: str ) -> None: super().__init__(model, request) @@ -843,7 +845,7 @@ class NotificationTemplateCollectionLayout(DefaultLayout): def __init__( self, model: NotificationTemplateCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, subtitle: str | None = None ) -> None: super().__init__(model, request) @@ -884,12 +886,12 @@ def editbar_links(self) -> list[Link | LinkGroup] | None: class NotificationTemplateLayout(DefaultLayout): - model: 'NotificationTemplate' + model: NotificationTemplate def __init__( self, - model: 'NotificationTemplate', - request: 'FeriennetRequest', + model: NotificationTemplate, + request: FeriennetRequest, subtitle: str | None = None ) -> None: super().__init__(model, request) @@ -922,13 +924,13 @@ def breadcrumbs(self) -> list[Link]: class VolunteerLayout(DefaultLayout): - model: 'VolunteerCollection' + model: VolunteerCollection if TYPE_CHECKING: def __init__( self, - model: 'VolunteerCollection', - request: 'FeriennetRequest' + model: VolunteerCollection, + request: FeriennetRequest ) -> None: ... @cached_property @@ -960,13 +962,13 @@ def breadcrumbs(self) -> list[Link]: class HomepageLayout(DefaultLayout): - model: 'Organisation' + model: Organisation if TYPE_CHECKING: def __init__( self, - model: 'Organisation', - request: 'FeriennetRequest' + model: Organisation, + request: FeriennetRequest ) -> None: ... @property diff --git a/src/onegov/feriennet/models/__init__.py b/src/onegov/feriennet/models/__init__.py index 0ee08acd64..691802d340 100644 --- a/src/onegov/feriennet/models/__init__.py +++ b/src/onegov/feriennet/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.feriennet.models.activity import VacationActivity from onegov.feriennet.models.calendar import Calendar, AttendeeCalendar from onegov.feriennet.models.group_invite import GroupInvite diff --git a/src/onegov/feriennet/models/activity.py b/src/onegov/feriennet/models/activity.py index 540562fa72..ec4e29f773 100644 --- a/src/onegov/feriennet/models/activity.py +++ b/src/onegov/feriennet/models/activity.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.activity import Activity, ActivityCollection, Occasion from onegov.activity import PublicationRequestCollection @@ -73,7 +75,7 @@ def organiser(self) -> list[str]: def ordered_tags( self, - request: 'FeriennetRequest', + request: FeriennetRequest, durations: int | None = None ) -> list[str]: @@ -105,7 +107,7 @@ class ActivityTicket(OrgTicketMixin, Ticket): def reference_group( self, - request: 'FeriennetRequest' # type:ignore[override] + request: FeriennetRequest # type:ignore[override] ) -> str: return self.handler.title @@ -127,7 +129,7 @@ def activity(self) -> Activity | None: return self.publication_request.activity @cached_property - def publication_request(self) -> 'PublicationRequest | None': + def publication_request(self) -> PublicationRequest | None: return self.collection.by_id(self.id) @property @@ -153,7 +155,7 @@ def group(self) -> str: return _('Activity') @property - def extra_data(self) -> 'Sequence[str]': + def extra_data(self) -> Sequence[str]: return () @property @@ -174,8 +176,8 @@ def ticket_deletable(self) -> bool: def get_summary( self, - request: 'FeriennetRequest' # type:ignore[override] - ) -> 'Markup': + request: FeriennetRequest # type:ignore[override] + ) -> Markup: assert self.publication_request is not None assert self.activity is not None @@ -198,8 +200,8 @@ def get_summary( def get_period_bound_links( self, - request: 'FeriennetRequest' - ) -> 'Iterator[Link]': + request: FeriennetRequest + ) -> Iterator[Link]: if self.activity is None: return @@ -247,7 +249,7 @@ def get_period_bound_links( def get_links( # type:ignore[override] self, - request: 'FeriennetRequest' # type:ignore[override] + request: FeriennetRequest # type:ignore[override] ) -> list[Link]: links = list(self.get_period_bound_links(request)) diff --git a/src/onegov/feriennet/models/calendar.py b/src/onegov/feriennet/models/calendar.py index 51a603a428..e5d4570618 100644 --- a/src/onegov/feriennet/models/calendar.py +++ b/src/onegov/feriennet/models/calendar.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import icalendar from onegov.activity import Attendee @@ -42,7 +44,7 @@ class Calendar: """ A base for all calendars that return icalendar renderings. """ name: ClassVar[str] - calendars: ClassVar[dict[str, type['Calendar']]] = {} + calendars: ClassVar[dict[str, type[Calendar]]] = {} def __init_subclass__(cls, name: str, **kwargs: Any) -> None: super().__init_subclass__(**kwargs) @@ -52,22 +54,22 @@ def __init_subclass__(cls, name: str, **kwargs: Any) -> None: cls.calendars[name] = cls @classmethod - def from_token(cls, session: 'Session', token: str) -> 'Calendar | None': + def from_token(cls, session: Session, token: str) -> Calendar | None: raise NotImplementedError @classmethod def from_name_and_token( cls, - session: 'Session', + session: Session, name: str, token: str - ) -> 'Calendar | None': + ) -> Calendar | None: calendar = cls.calendars.get(name) if calendar is None: return None return calendar.from_token(session, token) - def calendar(self, request: 'FeriennetRequest') -> bytes: + def calendar(self, request: FeriennetRequest) -> bytes: raise NotImplementedError def new(self) -> icalendar.Calendar: @@ -82,12 +84,12 @@ def new(self) -> icalendar.Calendar: class AttendeeCalendar(Calendar, name='attendee'): """ Renders all confirmed activites of the given attendee. """ - def __init__(self, session: 'Session', attendee: Attendee) -> None: + def __init__(self, session: Session, attendee: Attendee) -> None: self.session = session self.attendee = attendee @property - def attendee_calendar(self) -> 'Alias': + def attendee_calendar(self) -> Alias: return as_selectable_from_path( module_path('onegov.feriennet', 'queries/attendee_calendar.sql')) @@ -100,7 +102,7 @@ def token(self) -> str: return self.attendee.subscription_token @classmethod - def from_token(cls, session: 'Session', token: str) -> 'Self | None': + def from_token(cls, session: Session, token: str) -> Self | None: attendee = ( session.query(Attendee) .filter_by(subscription_token=token) @@ -109,7 +111,7 @@ def from_token(cls, session: 'Session', token: str) -> 'Self | None': return cls(session, attendee) if attendee else None - def calendar(self, request: 'FeriennetRequest') -> bytes: + def calendar(self, request: FeriennetRequest) -> bytes: calendar = self.new() calendar.add('x-wr-calname', self.attendee.name) @@ -123,8 +125,8 @@ def calendar(self, request: 'FeriennetRequest') -> bytes: def events( self, - request: 'FeriennetRequest' - ) -> 'Iterator[icalendar.Event]': + request: FeriennetRequest + ) -> Iterator[icalendar.Event]: session = request.session stmt = self.attendee_calendar diff --git a/src/onegov/feriennet/models/group_invite.py b/src/onegov/feriennet/models/group_invite.py index e682c4438a..47706ad5ff 100644 --- a/src/onegov/feriennet/models/group_invite.py +++ b/src/onegov/feriennet/models/group_invite.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.activity.models import Attendee, Booking, Occasion, Period from onegov.activity.utils import random_group_code @@ -17,7 +19,7 @@ class GroupInvite: def __init__( self, - session: 'Session', + session: Session, group_code: str, username: str | None ) -> None: @@ -26,7 +28,7 @@ def __init__( self.username = username @classmethod - def create(cls, session: 'Session', username: str | None) -> 'Self': + def create(cls, session: Session, username: str | None) -> Self: """ Creates a new group invite with a code that is not yet used. """ candidate = cls( session=session, group_code=random_group_code(), username=username) @@ -37,7 +39,7 @@ def create(cls, session: 'Session', username: str | None) -> 'Self': return candidate - def for_username(self, username: str | None) -> 'Self': + def for_username(self, username: str | None) -> Self: return self.__class__(self.session, self.group_code, username) @cached_property @@ -57,7 +59,7 @@ def exists(self) -> bool: """ return self.session.query(self.bookings().exists()).scalar() - def bookings(self) -> 'Query[Booking]': + def bookings(self) -> Query[Booking]: """ Returns a query of the bookings associated with this invite. """ return ( @@ -101,7 +103,7 @@ def attendees(self) -> tuple[tuple[Attendee, Booking], ...]: def prospects( self, username: str - ) -> 'Iterator[tuple[Attendee, Booking | None]]': + ) -> Iterator[tuple[Attendee, Booking | None]]: """ Returns the attendees associated with the given users that are not yet part of the group. diff --git a/src/onegov/feriennet/models/invoice_action.py b/src/onegov/feriennet/models/invoice_action.py index 964930303e..b03ab7092b 100644 --- a/src/onegov/feriennet/models/invoice_action.py +++ b/src/onegov/feriennet/models/invoice_action.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from datetime import date from onegov.activity import InvoiceItem @@ -14,8 +16,8 @@ class InvoiceAction: def __init__( self, - session: 'Session', - id: 'UUID', + session: Session, + id: UUID, action: Literal['mark-paid', 'mark-unpaid', 'remove-manual'], extend_to: Literal['invoice', 'family'] | None = None, text: str | None = None @@ -47,7 +49,7 @@ def valid(self) -> bool: return True @property - def targets(self) -> 'Iterator[InvoiceItem]': + def targets(self) -> Iterator[InvoiceItem]: item = self.item if item: @@ -83,20 +85,20 @@ def execute(self) -> None: def assert_safe_to_change( self, - targets: 'Collection[InvoiceItem]' + targets: Collection[InvoiceItem] ) -> None: for target in targets: if target.invoice.disable_changes_for_items((target, )): raise RuntimeError('Item was paid online') - def execute_mark_paid(self, targets: 'Collection[InvoiceItem]') -> None: + def execute_mark_paid(self, targets: Collection[InvoiceItem]) -> None: self.assert_safe_to_change(targets) for target in targets: target.payment_date = date.today() target.paid = True - def execute_mark_unpaid(self, targets: 'Collection[InvoiceItem]') -> None: + def execute_mark_unpaid(self, targets: Collection[InvoiceItem]) -> None: self.assert_safe_to_change(targets) for target in targets: @@ -107,7 +109,7 @@ def execute_mark_unpaid(self, targets: 'Collection[InvoiceItem]') -> None: def execute_remove_manual( self, - targets: 'Collection[InvoiceItem]' + targets: Collection[InvoiceItem] ) -> None: self.assert_safe_to_change(targets) diff --git a/src/onegov/feriennet/models/message.py b/src/onegov/feriennet/models/message.py index eb8b5223ff..129a9a44a2 100644 --- a/src/onegov/feriennet/models/message.py +++ b/src/onegov/feriennet/models/message.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import Period from onegov.chat import Message from onegov.org.models.message import TicketMessageMixin @@ -17,16 +19,16 @@ class PeriodMessage(Message): 'polymorphic_identity': 'period' } - def link(self, request: 'FeriennetRequest') -> str: + def link(self, request: FeriennetRequest) -> str: return request.class_link(Period, {'id': self.channel_id}) @classmethod def create( cls, - period: 'Period | PeriodMeta', - request: 'FeriennetRequest', + period: Period | PeriodMeta, + request: FeriennetRequest, action: str - ) -> 'Self': + ) -> Self: assert request.current_username, 'reserved for logged-in users' return cls.bound_messages(request.session).add( @@ -48,11 +50,11 @@ class ActivityMessage(Message, TicketMessageMixin): @classmethod def create( # type:ignore[override] cls, - ticket: 'Ticket', - request: 'FeriennetRequest', + ticket: Ticket, + request: FeriennetRequest, action: str, **extra_meta: Any - ) -> 'Self': + ) -> Self: # FIXME: This used to pass a scalar extra_meta=extra_meta # so it's possible there are some messages where the # extra_meta is now nested inside .meta['extra_meta'] diff --git a/src/onegov/feriennet/models/notification_template.py b/src/onegov/feriennet/models/notification_template.py index dfa9378b1b..484ee4d443 100644 --- a/src/onegov/feriennet/models/notification_template.py +++ b/src/onegov/feriennet/models/notification_template.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from markupsafe import Markup from onegov.activity import BookingCollection, InvoiceCollection from onegov.core.orm import Base @@ -34,25 +36,25 @@ class NotificationTemplate(Base, ContentMixin, TimestampMixin): __tablename__ = 'notification_templates' #: holds the selected period id (not stored in the database) - period_id: 'uuid.UUID | None' = None + period_id: uuid.UUID | None = None #: The public id of the notification template - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The subject of the notification - subject: 'Column[str]' = Column(Text, nullable=False, unique=True) + subject: Column[str] = Column(Text, nullable=False, unique=True) #: The template text in html, fully rendered html content - text: 'Column[str]' = Column(Text, nullable=False) + text: Column[str] = Column(Text, nullable=False) #: The date the notification was last sent - last_sent: 'Column[datetime | None]' = Column(UTCDateTime, nullable=True) + last_sent: Column[datetime | None] = Column(UTCDateTime, nullable=True) - def for_period(self, period: 'Period') -> 'Self': + def for_period(self, period: Period) -> Self: """ Implements the required interface for the 'periods' macro in onegov.feriennet. @@ -63,13 +65,13 @@ def for_period(self, period: 'Period') -> 'Self': class TemplateVariables: - bound: dict[str, 'BoundCallable'] + bound: dict[str, BoundCallable] expanded: dict[str, str] def __init__( self, - request: 'FeriennetRequest', - period: 'Period | None' + request: FeriennetRequest, + period: Period | None ) -> None: self.request = request self.period = period @@ -106,7 +108,7 @@ def bind( self, name: str, description: str, - method: 'Callable[[], str]' + method: Callable[[], str] ) -> None: assert hasattr(method, '__func__') diff --git a/src/onegov/feriennet/models/volunteer_cart.py b/src/onegov/feriennet/models/volunteer_cart.py index c4d866f99e..b965d74ab0 100644 --- a/src/onegov/feriennet/models/volunteer_cart.py +++ b/src/onegov/feriennet/models/volunteer_cart.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from itertools import groupby from onegov.activity import OccasionNeed from onegov.core.orm.sql import as_selectable_from_path @@ -40,32 +42,32 @@ class VolunteerCart: def __init__( self, - session: 'Session', - browser_session: 'BrowserSession' + session: Session, + browser_session: BrowserSession ) -> None: self.session = session self.browser_session = browser_session @classmethod - def from_request(cls, request: 'FeriennetRequest') -> 'Self': + def from_request(cls, request: FeriennetRequest) -> Self: return cls(request.session, request.browser_session) - def add(self, need_id: 'UUID') -> None: + def add(self, need_id: UUID) -> None: items: list[UUID] = self.browser_session.get('volunteer_cart', []) items.append(need_id) self.browser_session.volunteer_cart = items - def remove(self, need_id: 'UUID') -> None: + def remove(self, need_id: UUID) -> None: self.browser_session.volunteer_cart = [ i for i in self.browser_session.get('volunteer_cart', ()) if i != need_id ] - def has(self, need_id: 'UUID') -> bool: + def has(self, need_id: UUID) -> bool: return need_id in self.ids() - def ids(self) -> 'Sequence[UUID]': + def ids(self) -> Sequence[UUID]: return self.browser_session.get('volunteer_cart', ()) def clear(self) -> None: @@ -74,8 +76,8 @@ def clear(self) -> None: def card_items( self, - need_id: 'UUID | None' = None - ) -> 'Query[CardItemRow]': + need_id: UUID | None = None + ) -> Query[CardItemRow]: stmt = as_selectable_from_path( module_path('onegov.feriennet', 'queries/card_items.sql')) @@ -87,7 +89,7 @@ def card_items( query = select(stmt.c).where(stmt.c.need_id.in_(need_ids)) return self.session.execute(query) - def overlaps(self, need_id: 'UUID') -> bool: + def overlaps(self, need_id: UUID) -> bool: need = self.session.query(OccasionNeed).filter_by(id=need_id).first() if not need: @@ -102,13 +104,13 @@ def overlaps(self, need_id: 'UUID') -> bool: def for_frontend( self, - layout: 'DefaultLayout', + layout: DefaultLayout, localize: bool = True - ) -> 'Iterator[RenderData]': + ) -> Iterator[RenderData]: grouped = groupby(self.card_items(), key=lambda i: i.need_id) - def date(record: 'CardItemRow') -> str: + def date(record: CardItemRow) -> str: start = record.start end = record.end if localize: @@ -116,7 +118,7 @@ def date(record: 'CardItemRow') -> str: end = layout.to_timezone(end, record.timezone) return layout.format_datetime_range(start, end) - def remove(record: 'CardItemRow') -> str: + def remove(record: CardItemRow) -> str: return layout.csrf_protected_url( layout.request.link( VolunteerCartAction('remove', record.need_id))) @@ -140,16 +142,16 @@ class VolunteerCartAction: def __init__( self, action: Literal['add', 'remove'], - target: 'UUID' + target: UUID ): self.action = action self.target = target def execute( self, - request: 'FeriennetRequest', + request: FeriennetRequest, cart: VolunteerCart - ) -> 'JSON_ro': + ) -> JSON_ro: if self.action == 'add': if cart.has(self.target): diff --git a/src/onegov/feriennet/path.py b/src/onegov/feriennet/path.py index c8374d3448..32222904dd 100644 --- a/src/onegov/feriennet/path.py +++ b/src/onegov/feriennet/path.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import ActivityFilter from onegov.activity import Attendee, AttendeeCollection from onegov.activity import Booking, BookingCollection @@ -38,7 +40,7 @@ 'pages': integer_range_converter }) def get_vacation_activities( - request: 'FeriennetRequest', + request: FeriennetRequest, app: FeriennetApp, pages: tuple[int, int] | None = None, filter: dict[str, list[str]] | None = None @@ -67,7 +69,7 @@ def get_vacation_activities( model=VacationActivity, path='/activity/{name}') def get_vacation_activity( - request: 'FeriennetRequest', + request: FeriennetRequest, name: str ) -> VacationActivity | None: return VacationActivityCollection( @@ -78,14 +80,14 @@ def get_vacation_activity( model=Occasion, path='/occasions/{id}', converters={'id': UUID}) -def get_occasion(request: 'FeriennetRequest', id: UUID) -> Occasion | None: +def get_occasion(request: FeriennetRequest, id: UUID) -> Occasion | None: return OccasionCollection(request.session).by_id(id) @FeriennetApp.path( model=PeriodCollection, path='/periods') -def get_periods(request: 'FeriennetRequest') -> PeriodCollection: +def get_periods(request: FeriennetRequest) -> PeriodCollection: return PeriodCollection(request.session) @@ -93,7 +95,7 @@ def get_periods(request: 'FeriennetRequest') -> PeriodCollection: model=Period, path='/period/{id}', converters={'id': UUID}) -def get_period(request: 'FeriennetRequest', id: UUID) -> Period | None: +def get_period(request: FeriennetRequest, id: UUID) -> Period | None: return PeriodCollection(request.session).by_id(id) @@ -102,7 +104,7 @@ def get_period(request: 'FeriennetRequest', id: UUID) -> Period | None: path='/my-bookings', converters={'period_id': UUID}) def get_my_bookings( - request: 'FeriennetRequest', + request: FeriennetRequest, app: FeriennetApp, period_id: UUID | None = None, username: str | None = None @@ -130,7 +132,7 @@ def get_my_bookings( model=Booking, path='/booking/{id}', converters={'id': UUID}) -def get_booking(request: 'FeriennetRequest', id: UUID) -> Booking | None: +def get_booking(request: FeriennetRequest, id: UUID) -> Booking | None: return BookingCollection(request.session).by_id(id) @@ -138,7 +140,7 @@ def get_booking(request: 'FeriennetRequest', id: UUID) -> Booking | None: model=Attendee, path='/attendee/{id}', converters={'id': UUID}) -def get_attendee(request: 'FeriennetRequest', id: UUID) -> Attendee | None: +def get_attendee(request: FeriennetRequest, id: UUID) -> Attendee | None: return AttendeeCollection(request.session).by_id(id) @@ -150,7 +152,7 @@ def get_attendee(request: 'FeriennetRequest', id: UUID) -> Attendee | None: 'states': [LiteralConverter(OccasionState)] }) def get_matches( - request: 'FeriennetRequest', + request: FeriennetRequest, app: FeriennetApp, period_id: UUID | None, states: list[OccasionState] | None = None @@ -179,7 +181,7 @@ def get_matches( } ) def get_billing( - request: 'FeriennetRequest', + request: FeriennetRequest, app: FeriennetApp, period_id: UUID, username: str | None = None, @@ -234,7 +236,7 @@ def get_invoice_action( path='/my-bills', converters={'invoice': UUID}) def get_my_invoices( - request: 'FeriennetRequest', + request: FeriennetRequest, app: FeriennetApp, username: str | None = None, invoice: UUID | None = None @@ -269,7 +271,7 @@ def get_my_invoices( path='/invoice-item/{id}', converters={'id': UUID}) def get_my_invoice_item( - request: 'FeriennetRequest', + request: FeriennetRequest, id: UUID ) -> InvoiceItem | None: return request.session.query(InvoiceItem).filter_by(id=id).first() @@ -280,7 +282,7 @@ def get_my_invoice_item( path='/attendees/{activity_name}', converters={'period_id': UUID}) def get_occasion_attendee_collection( - request: 'FeriennetRequest', + request: FeriennetRequest, app: FeriennetApp, activity_name: str, period_id: UUID | None = None @@ -349,7 +351,7 @@ def get_notification_template( model=Calendar, path='/calendar/{name}/{token}') def get_calendar( - request: 'FeriennetRequest', + request: FeriennetRequest, name: str, token: str ) -> Calendar | None: @@ -360,7 +362,7 @@ def get_calendar( model=GroupInvite, path='/join/{group_code}') def get_group_invite( - request: 'FeriennetRequest', + request: FeriennetRequest, group_code: str, username: str | None = None ) -> GroupInvite | None: @@ -382,7 +384,7 @@ def get_group_invite( path='/occasion-need/{id}', converters={'id': UUID}) def get_occasion_need( - request: 'FeriennetRequest', + request: FeriennetRequest, id: UUID ) -> OccasionNeed | None: return request.session.query(OccasionNeed).filter_by(id=id).first() @@ -391,7 +393,7 @@ def get_occasion_need( @FeriennetApp.path( model=VolunteerCart, path='/volunteer-cart') -def get_volunteer_cart(request: 'FeriennetRequest') -> VolunteerCart: +def get_volunteer_cart(request: FeriennetRequest) -> VolunteerCart: return VolunteerCart.from_request(request) @@ -400,7 +402,7 @@ def get_volunteer_cart(request: 'FeriennetRequest') -> VolunteerCart: path='/volunteer-cart-action/{action}/{target}', converters={'action': LiteralConverter('add', 'remove'), 'target': UUID}) def get_volunteer_cart_action( - request: 'FeriennetRequest', + request: FeriennetRequest, action: Literal['add', 'remove'], target: UUID ) -> VolunteerCartAction: @@ -412,7 +414,7 @@ def get_volunteer_cart_action( path='/volunteers/{period_id}', converters={'period_id': UUID}) def get_volunteers( - request: 'FeriennetRequest', + request: FeriennetRequest, period_id: UUID ) -> VolunteerCollection | None: @@ -434,5 +436,5 @@ def get_volunteers( model=Volunteer, path='/volunteer/{id}', converters={'id': UUID}) -def get_volunteer(request: 'FeriennetRequest', id: UUID) -> Volunteer | None: +def get_volunteer(request: FeriennetRequest, id: UUID) -> Volunteer | None: return VolunteerCollection(request.session, None).by_id(id) diff --git a/src/onegov/feriennet/policy.py b/src/onegov/feriennet/policy.py index d9aada8519..e228fda801 100644 --- a/src/onegov/feriennet/policy.py +++ b/src/onegov/feriennet/policy.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import Activity, Occasion from onegov.feriennet.const import VISIBLE_ACTIVITY_STATES from morepath.authentication import NO_IDENTITY @@ -22,14 +24,14 @@ def __init__(self, username: str | None, role: str | None) -> None: self.role = role @classmethod - def for_identity(cls, identity: 'Identity | NoIdentity | None') -> 'Self': + def for_identity(cls, identity: Identity | NoIdentity | None) -> Self: if identity is None or identity is NO_IDENTITY: return cls(None, None) else: assert hasattr(identity, 'role') return cls(identity.userid, identity.role) - def granted_subset(self, query: 'Query[T]') -> 'Query[T]': + def granted_subset(self, query: Query[T]) -> Query[T]: """ Limits the given activites query for the given user. """ if self.username is None or self.role not in ('admin', 'editor'): @@ -37,7 +39,7 @@ def granted_subset(self, query: 'Query[T]') -> 'Query[T]': else: return self.private_subset(query) - def public_subset(self, query: 'Query[T]') -> 'Query[T]': + def public_subset(self, query: Query[T]) -> Query[T]: """ Limits the given query to activites meant for the public. """ return query.filter(and_( Activity.state.in_(VISIBLE_ACTIVITY_STATES['anonymous']), @@ -48,7 +50,7 @@ def public_subset(self, query: 'Query[T]') -> 'Query[T]': ).exists() )) - def private_subset(self, query: 'Query[T]') -> 'Query[T]': + def private_subset(self, query: Query[T]) -> Query[T]: """ Limits the given query to activites meant for admins/owners. Admins see all the states and owners see the states of their own. diff --git a/src/onegov/feriennet/qrbill.py b/src/onegov/feriennet/qrbill.py index e218ee62ef..a39a6904b2 100644 --- a/src/onegov/feriennet/qrbill.py +++ b/src/onegov/feriennet/qrbill.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from base64 import b64encode from io import StringIO from onegov.feriennet import log @@ -46,9 +48,9 @@ def qr_iban(value: str) -> bool: def generate_qr_bill( schema: str, - request: 'FeriennetRequest', - user: 'User', - invoice: 'Invoice' + request: FeriennetRequest, + user: User, + invoice: Invoice ) -> bytes | None: """ Generates a QR Bill and returns it as base64 encoded SVG. """ diff --git a/src/onegov/feriennet/redirects.py b/src/onegov/feriennet/redirects.py index df2feb0912..991b373b4d 100644 --- a/src/onegov/feriennet/redirects.py +++ b/src/onegov/feriennet/redirects.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.feriennet import FeriennetApp from onegov.core.redirect import Redirect diff --git a/src/onegov/feriennet/request.py b/src/onegov/feriennet/request.py index 712b7c8a63..4fa54fa4f1 100644 --- a/src/onegov/feriennet/request.py +++ b/src/onegov/feriennet/request.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.org.request import OrgRequest @@ -9,7 +11,7 @@ class FeriennetRequest(OrgRequest): - app: 'FeriennetApp' + app: FeriennetApp @cached_property def is_organiser(self) -> bool: diff --git a/src/onegov/feriennet/security.py b/src/onegov/feriennet/security.py index cda4e07cd6..736f73c585 100644 --- a/src/onegov/feriennet/security.py +++ b/src/onegov/feriennet/security.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import Activity, ActivityCollection, Booking, Occasion from onegov.core.security import Public, Private, Personal from onegov.core.security.rules import has_permission_logged_in @@ -29,7 +31,7 @@ def is_owner(username: str, activity: Activity) -> bool: @FeriennetApp.permission_rule(model=object, permission=object) def local_has_permission_logged_in( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: object, permission: object ) -> bool: @@ -45,7 +47,7 @@ def local_has_permission_logged_in( @FeriennetApp.permission_rule(model=object, permission=Private) def has_private_permission_logged_in( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: object, permission: type[Private] ) -> bool: @@ -63,7 +65,7 @@ def has_private_permission_logged_in( @FeriennetApp.permission_rule(model=SiteCollection, permission=Private) def has_private_permission_site_collection( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: SiteCollection, permission: type[Private] ) -> bool: @@ -78,7 +80,7 @@ def has_private_permission_site_collection( @FeriennetApp.permission_rule(model=ImageFileCollection, permission=Private) def has_private_permission_image_collection( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: ImageFileCollection, permission: type[Private] ) -> bool: @@ -96,7 +98,7 @@ def has_private_permission_image_collection( @FeriennetApp.permission_rule(model=ActivityCollection, permission=Private) def has_private_permission_activity_collections( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: ActivityCollection[Any], permission: type[Private] ) -> bool: @@ -114,7 +116,7 @@ def has_private_permission_activity_collections( @FeriennetApp.permission_rule(model=Activity, permission=Private) def has_private_permission_activities( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: Activity, permission: type[Private] ) -> bool: @@ -132,7 +134,7 @@ def has_private_permission_activities( @FeriennetApp.permission_rule(model=Occasion, permission=Private) def has_private_permission_occasions( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: Occasion, permission: type[Private] ) -> bool: @@ -153,7 +155,7 @@ def has_private_permission_occasions( ) def has_private_permission_notifications( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: NotificationTemplateCollection, permission: type[Private] ) -> bool: @@ -168,7 +170,7 @@ def has_private_permission_notifications( @FeriennetApp.permission_rule(model=NotificationTemplate, permission=Private) def has_private_permission_notification( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: NotificationTemplate, permission: type[Private] ) -> bool: @@ -183,7 +185,7 @@ def has_private_permission_notification( @FeriennetApp.permission_rule(model=Activity, permission=Public, identity=None) def has_public_permission_not_logged_in( app: FeriennetApp, - identity: 'NoIdentity | None', + identity: NoIdentity | None, model: Activity, permission: type[Public] ) -> bool: @@ -195,7 +197,7 @@ def has_public_permission_not_logged_in( @FeriennetApp.permission_rule(model=Activity, permission=Public) def has_public_permission_logged_in( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: Activity, permission: type[Public] ) -> bool: @@ -216,7 +218,7 @@ def has_public_permission_logged_in( @FeriennetApp.permission_rule(model=Booking, permission=Personal) def has_personal_permission_booking( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: Booking, permission: type[Personal] ) -> bool: @@ -234,7 +236,7 @@ def has_personal_permission_booking( ) def has_private_permission_occasion_attendee_collection( app: FeriennetApp, - identity: 'Identity', + identity: Identity, model: OccasionAttendeeCollection, permission: type[Private] ) -> bool: diff --git a/src/onegov/feriennet/sponsors/__init__.py b/src/onegov/feriennet/sponsors/__init__.py index c1b97dc28c..e3be03cc94 100644 --- a/src/onegov/feriennet/sponsors/__init__.py +++ b/src/onegov/feriennet/sponsors/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import time import yaml @@ -11,7 +13,7 @@ from typing import Self -def load_sponsors(sponsors_path: str) -> list['Sponsor']: +def load_sponsors(sponsors_path: str) -> list[Sponsor]: root = Path(sponsors_path) with (root / 'sponsors.yml').open('r') as f: @@ -35,29 +37,29 @@ def __init__(self, **kwargs: Any) -> None: for key, value in kwargs.items(): setattr(self, key, value) - def url_for(self, request: 'FeriennetRequest', path: str) -> str: + def url_for(self, request: FeriennetRequest, path: str) -> str: assert path.startswith('sponsors/') return request.link(StaticFile(path, version=request.app.version)) @overload def compiled( self, - request: 'FeriennetRequest', + request: FeriennetRequest, data: None = None - ) -> 'Self': ... + ) -> Self: ... @overload def compiled( self, - request: 'FeriennetRequest', + request: FeriennetRequest, data: dict[str, Any] - ) -> 'dict[str, Any]': ... + ) -> dict[str, Any]: ... def compiled( self, - request: 'FeriennetRequest', + request: FeriennetRequest, data: dict[str, Any] | None = None - ) -> 'Self | dict[str, Any]': + ) -> Self | dict[str, Any]: """ Returns an instance of the sponsor with all data localized and all variables replaced with the related values. diff --git a/src/onegov/feriennet/templates/notification_template_form.pt b/src/onegov/feriennet/templates/notification_template_form.pt index 202765688e..bfc13f90ae 100644 --- a/src/onegov/feriennet/templates/notification_template_form.pt +++ b/src/onegov/feriennet/templates/notification_template_form.pt @@ -6,7 +6,7 @@
-
+

Variables

diff --git a/src/onegov/feriennet/theme/__init__.py b/src/onegov/feriennet/theme/__init__.py index 10f4f67ea4..c0a84ec2ea 100644 --- a/src/onegov/feriennet/theme/__init__.py +++ b/src/onegov/feriennet/theme/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.feriennet.theme.feriennet_theme import FeriennetTheme __all__ = ['FeriennetTheme'] diff --git a/src/onegov/feriennet/theme/feriennet_theme.py b/src/onegov/feriennet/theme/feriennet_theme.py index c1e6918f10..86756a1ef8 100644 --- a/src/onegov/feriennet/theme/feriennet_theme.py +++ b/src/onegov/feriennet/theme/feriennet_theme.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import module_path from onegov.org.theme import OrgTheme diff --git a/src/onegov/feriennet/translations.py b/src/onegov/feriennet/translations.py index 1dd54b641d..9864d653c8 100644 --- a/src/onegov/feriennet/translations.py +++ b/src/onegov/feriennet/translations.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.feriennet import _ # translations provided by onegov.org, overriden by feriennet diff --git a/src/onegov/feriennet/upgrade.py b/src/onegov/feriennet/upgrade.py index faf5fd91a8..e12baa52f4 100644 --- a/src/onegov/feriennet/upgrade.py +++ b/src/onegov/feriennet/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + import textwrap from typing import TYPE_CHECKING @@ -186,7 +188,7 @@ def add_donation_page(context: UpgradeContext) -> None: ) -def as_paragraphs(text: str) -> 'Iterator[Markup]': +def as_paragraphs(text: str) -> Iterator[Markup]: paragraph: list[str] = [] for line in text.splitlines(): diff --git a/src/onegov/feriennet/utils.py b/src/onegov/feriennet/utils.py index e732945a76..78b63b4d63 100644 --- a/src/onegov/feriennet/utils.py +++ b/src/onegov/feriennet/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from contextlib import suppress @@ -31,7 +33,7 @@ def decode_name(fullname: str | None) -> tuple[str | None, str | None]: def parse_donation_amounts(text: str) -> tuple[float, ...]: lines = (stripped for l in text.splitlines() if (stripped := l.strip())) - def amounts() -> 'Iterator[float]': + def amounts() -> Iterator[float]: for line in lines: with suppress(ValueError): amount = float(line) @@ -42,8 +44,8 @@ def amounts() -> 'Iterator[float]': return tuple(amounts()) -def format_donation_amounts(amounts: 'Iterable[Decimal | float]') -> str: - def lines() -> 'Iterator[str]': +def format_donation_amounts(amounts: Iterable[Decimal | float]) -> str: + def lines() -> Iterator[str]: for amount in amounts: if float(amount).is_integer(): yield f'{int(amount):d}' diff --git a/src/onegov/feriennet/views/activity.py b/src/onegov/feriennet/views/activity.py index 2cdd2e7239..b3fcd67d1d 100644 --- a/src/onegov/feriennet/views/activity.py +++ b/src/onegov/feriennet/views/activity.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate import random @@ -73,7 +75,7 @@ def get_activity_form_class( model: VacationActivity | VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> type[VacationActivityForm]: if isinstance(model, VacationActivityCollection): @@ -83,7 +85,7 @@ def get_activity_form_class( def occasions_by_period( - session: 'Session', + session: Session, activity: Activity, show_inactive: bool, show_archived: bool @@ -125,7 +127,7 @@ def filter_link( def filter_timelines( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> list[Link]: links = [ @@ -158,7 +160,7 @@ def filter_timelines( def filter_tags( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> list[Link]: links = [ @@ -175,7 +177,7 @@ def filter_tags( def filter_durations( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> tuple[Link, ...]: return tuple( @@ -193,7 +195,7 @@ def filter_durations( def filter_ages( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> tuple[Link, ...]: ages = activity.available_ages() @@ -201,7 +203,7 @@ def filter_ages( if not ages: return () - def age_filters() -> 'Iterator[tuple[str, tuple[int, int]]]': + def age_filters() -> Iterator[tuple[str, tuple[int, int]]]: for age in range(*ages): if age < 16: yield str(age), (age, age) @@ -220,7 +222,7 @@ def age_filters() -> 'Iterator[tuple[str, tuple[int, int]]]': def filter_price_range( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> tuple[Link, ...]: return tuple( @@ -240,7 +242,7 @@ def filter_price_range( def filter_weeks( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> tuple[Link, ...]: # FIXME: format_date should be available on the request, so we don't @@ -264,7 +266,7 @@ def filter_weeks( def filter_weekdays( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> tuple[Link, ...]: return tuple( @@ -278,7 +280,7 @@ def filter_weekdays( def filter_available( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> tuple[Link, ...]: # NOTE: We're helping out mypy's inference here, since it won't @@ -302,7 +304,7 @@ def filter_available( def filter_municipalities( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> list[Link]: links = [ @@ -320,7 +322,7 @@ def filter_municipalities( def filter_periods( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> list[Link]: links = [ @@ -337,7 +339,7 @@ def filter_periods( def filter_own( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> tuple[Link, ...]: assert request.current_username is not None @@ -354,7 +356,7 @@ def filter_own( def filter_states( activity: VacationActivityCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> tuple[Link, ...]: return tuple( @@ -368,7 +370,7 @@ def filter_states( def period_bound_occasions( activity: Activity, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> list[Occasion]: active_period = request.app.active_period @@ -381,14 +383,14 @@ def period_bound_occasions( def activity_ages( activity: Activity, - request: 'FeriennetRequest' -) -> tuple['BoundedIntegerRange', ...]: + request: FeriennetRequest +) -> tuple[BoundedIntegerRange, ...]: return tuple(o.age for o in period_bound_occasions(activity, request)) def activity_spots( activity: Activity, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> int: if not request.app.active_period: @@ -404,8 +406,8 @@ def activity_spots( def activity_min_cost( activity: Activity, - request: 'FeriennetRequest' -) -> 'Decimal | None': + request: FeriennetRequest +) -> Decimal | None: occasions = period_bound_occasions(activity, request) @@ -417,8 +419,8 @@ def activity_min_cost( def activity_max_cost( activity: Activity, - request: 'FeriennetRequest' -) -> 'Decimal | None': + request: FeriennetRequest +) -> Decimal | None: occasions = period_bound_occasions(activity, request) @@ -428,7 +430,7 @@ def activity_max_cost( return max(o.total_cost for o in occasions) -def is_filtered(filters: dict[str, 'Sequence[Link]']) -> bool: +def is_filtered(filters: dict[str, Sequence[Link]]) -> bool: for links in filters.values(): for link in links: if link.active: @@ -438,7 +440,7 @@ def is_filtered(filters: dict[str, 'Sequence[Link]']) -> bool: def adjust_filter_path( - filters: dict[str, 'Sequence[Link]'], + filters: dict[str, Sequence[Link]], suffix: str ) -> None: @@ -450,8 +452,8 @@ def adjust_filter_path( def exclude_filtered_dates( activities: VacationActivityCollection, - dates: 'Iterable[OccasionDate]' -) -> list['OccasionDate']: + dates: Iterable[OccasionDate] +) -> list[OccasionDate]: today = date.today() return [ @@ -486,8 +488,8 @@ def exclude_filtered_dates( permission=Public) def view_activities( self: VacationActivityCollection, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: active_period = request.app.active_period show_activities = bool(active_period or request.is_organiser) @@ -549,27 +551,27 @@ def view_activities( ) def view_activities_as_json( self: VacationActivityCollection, - request: 'FeriennetRequest' -) -> 'JSON_ro': + request: FeriennetRequest +) -> JSON_ro: self.filter.states = {'accepted'} active_period = request.app.active_period - def image(activity: VacationActivity) -> 'JSON_ro': + def image(activity: VacationActivity) -> JSON_ro: url = (activity.meta or {}).get('thumbnail') return { 'thumbnail': url, 'full': url.replace('/thumbnail', '') if url else None } - def age(activity: VacationActivity) -> 'JSON_ro': + def age(activity: VacationActivity) -> JSON_ro: ages = activity_ages(activity, request) min_age = min(age.lower for age in ages) if ages else None max_age = max(age.upper - 1 for age in ages) if ages else None return {'min': min_age, 'max': max_age} - def cost(activity: VacationActivity) -> 'JSON_ro': + def cost(activity: VacationActivity) -> JSON_ro: min_cost = activity_min_cost(activity, request) max_cost = activity_max_cost(activity, request) return { @@ -577,7 +579,7 @@ def cost(activity: VacationActivity) -> 'JSON_ro': 'max': float(max_cost) if max_cost is not None else 0.0 } - def dates(activity: VacationActivity) -> 'JSON_ro': + def dates(activity: VacationActivity) -> JSON_ro: occasion_dates = [] for occasion in activity.occasions: for occasion_date in occasion.dates: @@ -595,12 +597,12 @@ def zip_code(activity: VacationActivity) -> int | None: match = search(r'(\d){4}', activity.location or '') return int(match.group()) if match else None - def coordinates(activity: VacationActivity) -> 'JSON_ro': + def coordinates(activity: VacationActivity) -> JSON_ro: lat = activity.coordinates.lat if activity.coordinates else None lon = activity.coordinates.lon if activity.coordinates else None return {'lat': lat, 'lon': lon} - def tags(activity: VacationActivity) -> 'JSON_ro': + def tags(activity: VacationActivity) -> JSON_ro: period = request.app.active_period period_id = period.id if period else None durations = sum({ @@ -657,8 +659,8 @@ def tags(activity: VacationActivity) -> 'JSON_ro': name='volunteer') def view_activities_for_volunteers( self: VacationActivityCollection, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: if not request.app.show_volunteers(request): raise exc.HTTPForbidden() @@ -720,8 +722,8 @@ def view_activities_for_volunteers( permission=Public) def view_activity( self: VacationActivity, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: session = request.session layout = VacationActivityLayout(self, request) @@ -733,7 +735,7 @@ def view_activity( .filter(Booking.occasion_id.in_(occasion_ids)) } or set() - def occasion_links(o: Occasion) -> 'Iterator[Link]': + def occasion_links(o: Occasion) -> Iterator[Link]: if not o.period.archived and (o.period.active or request.is_admin): yield Link(text=_('Edit'), url=request.link(o, name='edit')) @@ -887,9 +889,9 @@ def show_enroll(occasion: Occasion) -> bool: name='new') def new_activity( self: VacationActivityCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, form: VacationActivityForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): assert form.title.data is not None @@ -920,9 +922,9 @@ def new_activity( name='edit') def edit_activity( self: VacationActivity, - request: 'FeriennetRequest', + request: FeriennetRequest, form: VacationActivityForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): old_username = self.username @@ -966,7 +968,7 @@ def edit_activity( request_method='DELETE') def discard_activity( self: VacationActivity, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: request.assert_valid_csrf_token() @@ -993,7 +995,7 @@ def discard_activity( request_method='POST') def propose_activity( self: VacationActivity, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: assert request.app.active_period, 'An active period is required' @@ -1054,7 +1056,7 @@ def propose_activity( request.success(_('Thank you for your proposal!')) @request.after - def redirect_intercooler(response: 'Response') -> None: + def redirect_intercooler(response: Response) -> None: response.headers.add('X-IC-Redirect', request.link(ticket, 'status')) # do not redirect here, intercooler doesn't deal well with that... @@ -1068,7 +1070,7 @@ def redirect_intercooler(response: 'Response') -> None: request_method='POST') def accept_activity( self: VacationActivity, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: return administer_activity( @@ -1087,7 +1089,7 @@ def accept_activity( request_method='POST') def archive_activity( self: VacationActivity, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: return administer_activity( @@ -1106,7 +1108,7 @@ def archive_activity( request_method='POST') def offer_activity_again( self: VacationActivity, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: assert self.state in ('archived', 'preview') @@ -1115,14 +1117,14 @@ def offer_activity_again( self.state = 'preview' @request.after - def redirect_intercooler(response: 'Response') -> None: + def redirect_intercooler(response: Response) -> None: response.headers.add('X-IC-Redirect', request.link(self, 'edit')) def relevant_ticket( activity: VacationActivity, - request: 'FeriennetRequest' -) -> 'Ticket | None': + request: FeriennetRequest +) -> Ticket | None: pr = (activity.request_by_period(request.app.active_period) or activity.latest_request) @@ -1134,7 +1136,7 @@ def relevant_ticket( def administer_activity( model: VacationActivity, - request: 'FeriennetRequest', + request: FeriennetRequest, action: str, template: str, subject: str @@ -1163,7 +1165,7 @@ def administer_activity( ActivityMessage.create(ticket, request, action) @request.after - def redirect_intercooler(response: 'Response') -> None: + def redirect_intercooler(response: Response) -> None: response.headers.add('X-IC-Redirect', request.link(ticket)) # do not redirect here, intercooler doesn't deal well with that... diff --git a/src/onegov/feriennet/views/attendee.py b/src/onegov/feriennet/views/attendee.py index e2294be9ba..00279cb55e 100644 --- a/src/onegov/feriennet/views/attendee.py +++ b/src/onegov/feriennet/views/attendee.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import Attendee, BookingCollection from onegov.core.security import Personal from onegov.feriennet import FeriennetApp, _ @@ -20,9 +22,9 @@ template='form.pt') def edit_attendee( self: Attendee, - request: 'FeriennetRequest', + request: FeriennetRequest, form: AttendeeForm -) -> 'RenderData | Response': +) -> RenderData | Response: # note: attendees are added in the views/occasion.py file assert request.is_admin or self.username == request.current_username @@ -60,9 +62,9 @@ def edit_attendee( template='form.pt') def edit_attendee_limit( self: Attendee, - request: 'FeriennetRequest', + request: FeriennetRequest, form: AttendeeLimitForm -) -> 'RenderData | Response': +) -> RenderData | Response: assert request.is_admin or self.username == request.current_username diff --git a/src/onegov/feriennet/views/auth.py b/src/onegov/feriennet/views/auth.py index b5855a79a3..34c25c3c7a 100644 --- a/src/onegov/feriennet/views/auth.py +++ b/src/onegov/feriennet/views/auth.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Public from onegov.feriennet import FeriennetApp, _ from onegov.org.views.auth import handle_registration @@ -18,9 +20,9 @@ ) def custom_handle_registration( self: Auth, - request: 'FeriennetRequest', + request: FeriennetRequest, form: RegistrationForm -) -> 'RenderData | Response': +) -> RenderData | Response: if request.app.org.meta.get('require_full_age_for_registration', False): form.callout = _( # type:ignore[attr-defined] diff --git a/src/onegov/feriennet/views/billing.py b/src/onegov/feriennet/views/billing.py index 2cadf5b48a..fba27a6c5d 100644 --- a/src/onegov/feriennet/views/billing.py +++ b/src/onegov/feriennet/views/billing.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from base64 import b64decode from gzip import GzipFile from io import BytesIO @@ -48,9 +50,9 @@ permission=Secret) def view_billing( self: BillingCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, form: BillingForm -) -> 'RenderData': +) -> RenderData: layout = BillingCollectionLayout(self, request) session = request.session @@ -88,7 +90,7 @@ def view_billing( def csrf_protected(url: str) -> str: return URL(url).query_param('csrf-token', csrf_token).as_string() - def as_link(action: InvoiceAction, traits: 'Iterable[Trait]') -> Link: + def as_link(action: InvoiceAction, traits: Iterable[Trait]) -> Link: traits = ( *traits, Intercooler(request_method='POST') @@ -130,7 +132,7 @@ def mark_paid_with_date_link( url=url ) - def invoice_links(details: BillingCollection.Bill) -> 'Iterator[Link]': + def invoice_links(details: BillingCollection.Bill) -> Iterator[Link]: if not self.period.finalized: return @@ -189,7 +191,7 @@ def invoice_links(details: BillingCollection.Bill) -> 'Iterator[Link]': yield from (as_link(a, traits) for a in invoice_actions(details)) - def item_links(item: 'InvoicesByPeriodRow') -> 'Iterator[Link]': + def item_links(item: InvoicesByPeriodRow) -> Iterator[Link]: if not self.period.finalized: return @@ -226,7 +228,7 @@ def item_links(item: 'InvoicesByPeriodRow') -> 'Iterator[Link]': def invoice_actions( details: BillingCollection.Bill - ) -> 'Iterator[InvoiceAction]': + ) -> Iterator[InvoiceAction]: if details.paid: yield InvoiceAction( @@ -245,7 +247,7 @@ def invoice_actions( text=_('Mark whole bill as paid') ) - def item_actions(item: 'InvoicesByPeriodRow') -> 'Iterator[InvoiceAction]': + def item_actions(item: InvoicesByPeriodRow) -> Iterator[InvoiceAction]: if item.paid: yield InvoiceAction( session=session, @@ -292,8 +294,8 @@ def item_actions(item: 'InvoicesByPeriodRow') -> 'Iterator[InvoiceAction]': request_method='POST') def reset_billing( self: BillingCollection, - request: 'FeriennetRequest' -) -> 'Response | None': + request: FeriennetRequest +) -> Response | None: if not self.period.active: request.warning( @@ -316,8 +318,8 @@ def reset_billing( template='online-payments.pt') def view_online_payments( self: BillingCollection, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: table = payments_association_table_for(InvoiceItem) session = request.session @@ -346,7 +348,7 @@ def view_online_payments( layout = OnlinePaymentsLayout(self, request, title=title) - def payment_actions(payment: Payment) -> 'Iterator[Link]': + def payment_actions(payment: Payment) -> Iterator[Link]: if payment.state == 'paid': assert payment.amount is not None amount = f'{payment.amount:02f} {payment.currency}' @@ -390,14 +392,14 @@ def payment_actions(payment: Payment) -> 'Iterator[Link]': request_method='POST') def execute_invoice_action( self: InvoiceAction, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: request.assert_valid_csrf_token() self.execute() @request.after - def trigger_bill_update(response: 'Response') -> None: + def trigger_bill_update(response: Response) -> None: if self.extend_to == 'family': response.headers.add('X-IC-Redirect', request.class_link( BillingCollection @@ -418,7 +420,7 @@ def trigger_bill_update(response: 'Response') -> None: permission=Secret) def view_execute_import( self: BillingCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: request.assert_valid_csrf_token() @@ -465,7 +467,7 @@ def view_execute_import( del request.browser_session['account-statement'] @request.after - def redirect_intercooler(response: 'Response') -> None: + def redirect_intercooler(response: Response) -> None: response.headers.add('X-IC-Redirect', request.link(self)) @@ -478,9 +480,9 @@ def redirect_intercooler(response: 'Response') -> None: ) def view_billing_import( self: BillingCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, form: BankStatementImportForm -) -> 'RenderData | Response': +) -> RenderData | Response: uploaded = 'account-statement' in request.browser_session @@ -566,9 +568,9 @@ def view_billing_import( ) def view_manual_booking_form( self: BillingCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, form: ManualBookingForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): assert form.text is not None @@ -599,9 +601,9 @@ def view_manual_booking_form( ) def view_paid_date_form( self: BillingCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, form: PaymentWithDateForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): assert form.items.data is not None diff --git a/src/onegov/feriennet/views/booking.py b/src/onegov/feriennet/views/booking.py index b042e80037..ec0ec2ec1f 100644 --- a/src/onegov/feriennet/views/booking.py +++ b/src/onegov/feriennet/views/booking.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import morepath import urllib.parse @@ -83,9 +85,9 @@ def all_bookings(collection: BookingCollection) -> list[Booking]: def group_bookings( - period: 'Period | PeriodMeta', - bookings: 'Iterable[Booking]' -) -> dict[Attendee, dict['BookingState', SortedList[Booking]]]: + period: Period | PeriodMeta, + bookings: Iterable[Booking] +) -> dict[Attendee, dict[BookingState, SortedList[Booking]]]: """ Takes a (small) list of bookings and groups them by attendee and state and sorting them by date. @@ -100,10 +102,10 @@ def group_bookings( ) if period.wishlist_phase: - def state(booking: Booking) -> 'BookingState': + def state(booking: Booking) -> BookingState: return 'open' else: - def state(booking: Booking) -> 'BookingState': + def state(booking: Booking) -> BookingState: return booking.state grouped: dict[Attendee, dict[BookingState, SortedList[Booking]]] = {} @@ -125,8 +127,8 @@ def state(booking: Booking) -> 'BookingState': def total_by_bookings( - period: 'Period | PeriodMeta | None', - bookings: 'Collection[Booking]' + period: Period | PeriodMeta | None, + bookings: Collection[Booking] ) -> Decimal: if bookings: @@ -145,9 +147,9 @@ def total_by_bookings( def related_attendees( - session: 'Session', - occasion_ids: 'Collection[UUID]' -) -> dict[UUID, list['RelatedAttendeeRow']]: + session: Session, + occasion_ids: Collection[UUID] +) -> dict[UUID, list[RelatedAttendeeRow]]: stmt = as_selectable_from_path( module_path('onegov.feriennet', 'queries/related_attendees.sql')) @@ -170,7 +172,7 @@ def related_attendees( def attendees_by_username( - request: 'FeriennetRequest', + request: FeriennetRequest, username: str ) -> list[Attendee]: """ Loads the given attendees linked to the given username, sorted by @@ -194,7 +196,7 @@ def get_booking_title(layout: DefaultLayout, booking: Booking) -> str: def actions_by_booking( layout: DefaultLayout, - period: 'Period | PeriodMeta | None', + period: Period | PeriodMeta | None, booking: Booking ) -> list[Link]: @@ -333,13 +335,13 @@ def actions_by_booking( def show_error_on_attendee( - request: 'FeriennetRequest', + request: FeriennetRequest, attendee: Attendee, message: str ) -> None: @request.after - def show_error(response: 'Response') -> None: + def show_error(response: Response) -> None: response.headers.add('X-IC-Trigger', 'show-alert') response.headers.add('X-IC-Trigger-Data', json.dumps({ 'type': 'alert', @@ -354,8 +356,8 @@ def show_error(response: 'Response') -> None: permission=Personal) def view_my_bookings( self: BookingCollection, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: assert self.username is not None attendees = attendees_by_username(request, self.username) @@ -416,7 +418,7 @@ def user_select_link(user: User) -> str: }) def occasion_attendees( - request: 'FeriennetRequest', + request: FeriennetRequest, username: str, occasion_id: UUID ) -> list[Attendee]: @@ -459,7 +461,7 @@ def occasion_attendees( model=Booking, permission=Personal, request_method='DELETE') -def delete_booking(self: Booking, request: 'FeriennetRequest') -> None: +def delete_booking(self: Booking, request: FeriennetRequest) -> None: request.assert_valid_csrf_token() if self.period.confirmed and self.state not in DELETABLE_STATES: @@ -471,7 +473,7 @@ def delete_booking(self: Booking, request: 'FeriennetRequest') -> None: BookingCollection(request.session).delete(self) @request.after - def remove_target(response: 'Response') -> None: + def remove_target(response: Response) -> None: response.headers.add('X-IC-Remove', 'true') @@ -480,7 +482,7 @@ def remove_target(response: 'Response') -> None: name='cancel', permission=Personal, request_method='POST') -def cancel_booking(self: Booking, request: 'FeriennetRequest') -> None: +def cancel_booking(self: Booking, request: FeriennetRequest) -> None: request.assert_valid_csrf_token() if not self.period.wishlist_phase: @@ -528,7 +530,7 @@ def cancel_booking(self: Booking, request: 'FeriennetRequest') -> None: ) @request.after - def update_matching(response: 'Response') -> None: + def update_matching(response: Response) -> None: response.headers.add('X-IC-Trigger', 'reload-from') response.headers.add('X-IC-Trigger-Data', json.dumps({ 'selector': f'#{self.occasion.id}' @@ -540,7 +542,7 @@ def update_matching(response: 'Response') -> None: name='toggle-star', permission=Personal, request_method='POST') -def toggle_star(self: Booking, request: 'FeriennetRequest') -> str: +def toggle_star(self: Booking, request: FeriennetRequest) -> str: if self.period.wishlist_phase: if not self.starred: @@ -562,7 +564,7 @@ def toggle_star(self: Booking, request: 'FeriennetRequest') -> str: name='toggle-nobble', permission=Secret, request_method='POST') -def toggle_nobble(self: Booking, request: 'FeriennetRequest') -> str: +def toggle_nobble(self: Booking, request: FeriennetRequest) -> str: if self.nobbled: self.unnobble() else: @@ -572,7 +574,7 @@ def toggle_nobble(self: Booking, request: 'FeriennetRequest') -> str: return render_macro(layout.macros['nobble'], request, {'booking': self}) -def render_css(content: str, request: 'FeriennetRequest') -> morepath.Response: +def render_css(content: str, request: FeriennetRequest) -> morepath.Response: response = morepath.Response(content) response.content_type = 'text/css' return response @@ -583,7 +585,7 @@ def render_css(content: str, request: 'FeriennetRequest') -> morepath.Response: name='mask', permission=Personal, render=render_css) -def view_mask(self: BookingCollection, request: 'FeriennetRequest') -> str: +def view_mask(self: BookingCollection, request: FeriennetRequest) -> str: # hackish way to get the single attendee print to work -> mask all the # attendees, except for the one given by param @@ -607,7 +609,7 @@ def view_mask(self: BookingCollection, request: 'FeriennetRequest') -> str: model=Booking, name='invite', permission=Personal) -def create_invite(self: Booking, request: 'FeriennetRequest') -> 'Response': +def create_invite(self: Booking, request: FeriennetRequest) -> Response: """ Creates a group_code on the booking, if one doesn't exist already and redirects to the GroupInvite view. @@ -629,8 +631,8 @@ def create_invite(self: Booking, request: 'FeriennetRequest') -> 'Response': template='invite.pt') def view_group_invite( self: GroupInvite, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: layout = GroupInviteLayout(self, request) occasion = self.occasion @@ -783,7 +785,7 @@ def user_select_link(user: User) -> str: permission=Personal, name='join', request_method='POST') -def join_group(self: GroupInvite, request: 'FeriennetRequest') -> None: +def join_group(self: GroupInvite, request: FeriennetRequest) -> None: request.assert_valid_csrf_token() booking_id = request.params.get('booking_id', None) @@ -811,7 +813,7 @@ def join_group(self: GroupInvite, request: 'FeriennetRequest') -> None: permission=Personal, name='leave', request_method='POST') -def leave_group(self: GroupInvite, request: 'FeriennetRequest') -> None: +def leave_group(self: GroupInvite, request: FeriennetRequest) -> None: request.assert_valid_csrf_token() booking_id = request.params.get('booking_id', None) diff --git a/src/onegov/feriennet/views/calendar.py b/src/onegov/feriennet/views/calendar.py index 3317263c65..83526b5a7e 100644 --- a/src/onegov/feriennet/views/calendar.py +++ b/src/onegov/feriennet/views/calendar.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath.request import Response from onegov.core.security import Public from onegov.feriennet import FeriennetApp @@ -14,7 +16,7 @@ permission=Public) def view_attendee_calendar( self: AttendeeCalendar, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> Response: return Response( self.calendar(request), diff --git a/src/onegov/feriennet/views/homepage.py b/src/onegov/feriennet/views/homepage.py index d618063425..dbb2e12acf 100644 --- a/src/onegov/feriennet/views/homepage.py +++ b/src/onegov/feriennet/views/homepage.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Public from onegov.org.views.homepage import view_org from onegov.org.models import Organisation @@ -19,6 +21,6 @@ ) def feriennet_view_org( self: Organisation, - request: 'FeriennetRequest' -) -> 'RenderData | Response': + request: FeriennetRequest +) -> RenderData | Response: return view_org(self, request, HomepageLayout(self, request)) diff --git a/src/onegov/feriennet/views/invoice.py b/src/onegov/feriennet/views/invoice.py index 1f17fb86a3..d40ae3940c 100644 --- a/src/onegov/feriennet/views/invoice.py +++ b/src/onegov/feriennet/views/invoice.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from decimal import Decimal from datetime import date from markupsafe import Markup @@ -35,8 +37,8 @@ ) def redirect_to_invoice_view( self: InvoiceItem, - request: 'FeriennetRequest' -) -> 'Response': + request: FeriennetRequest +) -> Response: return request.redirect( request.link( InvoiceCollection( @@ -55,8 +57,8 @@ def redirect_to_invoice_view( ) def view_creditcard_payments( self: InvoiceItem, - request: 'FeriennetRequest' -) -> 'Response': + request: FeriennetRequest +) -> Response: return request.redirect(request.class_link( BillingCollection, { @@ -72,8 +74,8 @@ def view_creditcard_payments( permission=Personal) def view_my_invoices( self: InvoiceCollection, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: query = PeriodCollection(request.session).query() query = query.filter(Period.finalized == True) @@ -136,7 +138,7 @@ def view_my_invoices( qr_bill_enabled = meta.get('bank_qr_bill', False) layout = InvoiceLayout(self, request, title) - def payment_button(title: str, price: 'Price | None') -> str | None: + def payment_button(title: str, price: Price | None) -> str | None: assert payment_provider is not None assert request.locale is not None price = payment_provider.adjust_price(price) @@ -190,8 +192,8 @@ def qr_bill(invoice: Invoice) -> bytes | None: request_method='POST') def handle_payment( self: InvoiceCollection, - request: 'FeriennetRequest' -) -> 'Response': + request: FeriennetRequest +) -> Response: provider = request.app.default_payment_provider assert provider is not None @@ -242,9 +244,9 @@ def handle_payment( name='donation') def handle_donation( self: InvoiceCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, form: DonationForm -) -> 'RenderData | Response': +) -> RenderData | Response: assert request.current_user is not None if not self.user_id: @@ -326,7 +328,7 @@ def handle_donation( request_method='DELETE') def handle_delete_donation( self: InvoiceCollection, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: assert self.user_id and self.period_id diff --git a/src/onegov/feriennet/views/match.py b/src/onegov/feriennet/views/match.py index 72cce04711..dfe869d29e 100644 --- a/src/onegov/feriennet/views/match.py +++ b/src/onegov/feriennet/views/match.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from decimal import Decimal from onegov.core.cache import lru_cache from onegov.activity import Attendee @@ -29,7 +31,7 @@ from webob import Response -OCCASION_STATES: tuple[tuple[str, 'OccasionState'], ...] = ( +OCCASION_STATES: tuple[tuple[str, OccasionState], ...] = ( (_('Too many attendees'), 'overfull'), (_('Fully occupied'), 'full'), (_('Enough attendees'), 'operable'), @@ -46,9 +48,9 @@ permission=Secret) def handle_matches( self: MatchCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, form: MatchForm -) -> 'RenderData | Response': +) -> RenderData | Response: layout = MatchCollectionLayout(self, request) @@ -84,10 +86,10 @@ def handle_matches( self.period = self.period.materialize(request.session) form.process_scoring(self.period.scoring) - def activity_link(oid: 'UUID') -> str: + def activity_link(oid: UUID) -> str: return request.class_link(Occasion, {'id': oid}) - def occasion_table_link(oid: 'UUID') -> str: + def occasion_table_link(oid: UUID) -> str: return request.class_link(Occasion, {'id': oid}, name='bookings-table') filters = { @@ -126,8 +128,8 @@ def occasion_table_link(oid: 'UUID') -> str: permission=Secret) def view_occasion_bookings_table( self: Occasion, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: layout = DefaultLayout(self, request) @@ -143,7 +145,7 @@ def view_occasion_bookings_table( ) } - def occasion_links(oid: 'UUID') -> 'Iterator[Link]': + def occasion_links(oid: UUID) -> Iterator[Link]: if self.period.finalized: yield Link( text=_('Signup Attendee'), @@ -182,7 +184,7 @@ def user_link(username: str) -> str: ) @lru_cache(maxsize=10) - def attendee_link(attendee_id: 'UUID') -> str: + def attendee_link(attendee_id: UUID) -> str: return request.return_here( request.class_link( Attendee, {'id': attendee_id} @@ -197,7 +199,7 @@ def group_link(group_code: str) -> str: } ) - def booking_links(booking: Booking) -> 'Iterator[Link]': + def booking_links(booking: Booking) -> Iterator[Link]: yield Link(_('User'), user_link(booking.attendee.username)) yield Link(_('Attendee'), attendee_link(booking.attendee_id)) yield Link(phase_title, bookings_link(booking.attendee.username)) @@ -300,7 +302,7 @@ def booking_links(booking: Booking) -> 'Iterator[Link]': request_method='POST') def reset_matching( self: MatchCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, quiet: bool = False ) -> None: diff --git a/src/onegov/feriennet/views/notification_template.py b/src/onegov/feriennet/views/notification_template.py index 147ea94f58..652bc65bf5 100644 --- a/src/onegov/feriennet/views/notification_template.py +++ b/src/onegov/feriennet/views/notification_template.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from markupsafe import escape @@ -28,7 +30,7 @@ from webob import Response -def get_variables(request: 'FeriennetRequest') -> dict[str, str]: +def get_variables(request: FeriennetRequest) -> dict[str, str]: period = PeriodCollection(request.session).active() variables = TemplateVariables(request, period).bound @@ -43,12 +45,12 @@ def get_variables(request: 'FeriennetRequest') -> dict[str, str]: template='notification_templates.pt') def view_notification_templates( self: NotificationTemplateCollection, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: layout = NotificationTemplateCollectionLayout(self, request) - def get_links(notification: NotificationTemplate) -> 'Iterator[Link]': + def get_links(notification: NotificationTemplate) -> Iterator[Link]: if not request.app.active_period: return @@ -88,9 +90,9 @@ def get_links(notification: NotificationTemplate) -> 'Iterator[Link]': form=NotificationTemplateForm) def view_notification_template_form( self: NotificationTemplateCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, form: NotificationTemplateForm -) -> 'RenderData | Response': +) -> RenderData | Response: title = _('New Notification Template') @@ -121,9 +123,9 @@ def view_notification_template_form( form=NotificationTemplateForm) def edit_notification( self: NotificationTemplate, - request: 'FeriennetRequest', + request: FeriennetRequest, form: NotificationTemplateForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): form.populate_obj(self) @@ -152,7 +154,7 @@ def edit_notification( request_method='DELETE') def delete_notification( self: NotificationTemplate, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: request.assert_valid_csrf_token() @@ -160,7 +162,7 @@ def delete_notification( NotificationTemplateCollection(request.session).delete(self) @request.after - def remove_target(response: 'Response') -> None: + def remove_target(response: Response) -> None: response.headers.add('X-IC-Remove', 'true') @@ -173,9 +175,9 @@ def remove_target(response: 'Response') -> None: ) def handle_send_notification( self: NotificationTemplate, - request: 'FeriennetRequest', + request: FeriennetRequest, form: NotificationTemplateSendForm -) -> 'RenderData | Response': +) -> RenderData | Response: period = PeriodCollection(request.session).active() variables = TemplateVariables(request, period) @@ -197,7 +199,7 @@ def handle_send_notification( }) plaintext = html_to_text(content) - def email_iter() -> 'Iterator[EmailJsonDict]': + def email_iter() -> Iterator[EmailJsonDict]: for recipient in recipients: yield request.app.prepare_email( receivers=(recipient, ), diff --git a/src/onegov/feriennet/views/occasion.py b/src/onegov/feriennet/views/occasion.py index 8a77bbeabd..7863ef7a56 100644 --- a/src/onegov/feriennet/views/occasion.py +++ b/src/onegov/feriennet/views/occasion.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from markupsafe import Markup from onegov.activity import AttendeeCollection @@ -30,7 +32,7 @@ model=Occasion, permission=Public, ) -def view_occasion(self: Occasion, request: 'FeriennetRequest') -> 'Response': +def view_occasion(self: Occasion, request: FeriennetRequest) -> Response: return request.redirect(request.link(self.activity)) @@ -42,9 +44,9 @@ def view_occasion(self: Occasion, request: 'FeriennetRequest') -> 'Response': name='new-occasion') def new_occasion( self: VacationActivity, - request: 'FeriennetRequest', + request: FeriennetRequest, form: OccasionForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): occasions = OccasionCollection(request.session) @@ -81,9 +83,9 @@ def new_occasion( name='clone') def clone_occasion( self: Occasion, - request: 'FeriennetRequest', + request: FeriennetRequest, form: OccasionForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): occasions = OccasionCollection(request.session) @@ -121,9 +123,9 @@ def clone_occasion( name='edit') def edit_occasion( self: Occasion, - request: 'FeriennetRequest', + request: FeriennetRequest, form: OccasionForm -) -> 'RenderData | Response': +) -> RenderData | Response: if self.period.confirmed: warning = _( @@ -156,7 +158,7 @@ def edit_occasion( model=Occasion, permission=Private, request_method='DELETE') -def delete_occasion(self: Occasion, request: 'FeriennetRequest') -> None: +def delete_occasion(self: Occasion, request: FeriennetRequest) -> None: request.assert_valid_csrf_token() OccasionCollection(request.session).delete(self) @@ -167,7 +169,7 @@ def delete_occasion(self: Occasion, request: 'FeriennetRequest') -> None: permission=Private, request_method='POST', name='cancel') -def cancel_occasion(self: Occasion, request: 'FeriennetRequest') -> None: +def cancel_occasion(self: Occasion, request: FeriennetRequest) -> None: request.assert_valid_csrf_token() self.cancel() @@ -178,7 +180,7 @@ def cancel_occasion(self: Occasion, request: 'FeriennetRequest') -> None: permission=Private, request_method='POST', name='reinstate') -def reinstate_occasion(self: Occasion, request: 'FeriennetRequest') -> None: +def reinstate_occasion(self: Occasion, request: FeriennetRequest) -> None: request.assert_valid_csrf_token() self.cancelled = False @@ -192,9 +194,9 @@ def reinstate_occasion(self: Occasion, request: 'FeriennetRequest') -> None: template='enroll_form.pt') def book_occasion( self: Occasion, - request: 'FeriennetRequest', + request: FeriennetRequest, form: AttendeeSignupForm -) -> 'RenderData | Response': +) -> RenderData | Response: # for the "nth. occasion" title number: int = request.session.execute(""" @@ -382,9 +384,9 @@ def book_occasion( name='add-need') def handle_new_occasion_need( self: Occasion, - request: 'FeriennetRequest', + request: FeriennetRequest, form: OccasionNeedForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): assert form.name.data is not None @@ -415,9 +417,9 @@ def handle_new_occasion_need( name='edit') def handle_occasion_need( self: OccasionNeed, - request: 'FeriennetRequest', + request: FeriennetRequest, form: OccasionNeedForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): form.populate_obj(self) @@ -446,7 +448,7 @@ def handle_occasion_need( request_method='DELETE') def delete_occasion_need( self: OccasionNeed, - request: 'FeriennetRequest' + request: FeriennetRequest ) -> None: request.assert_valid_csrf_token() diff --git a/src/onegov/feriennet/views/occasion_attendees.py b/src/onegov/feriennet/views/occasion_attendees.py index 636cc1818a..87cfa78fa6 100644 --- a/src/onegov/feriennet/views/occasion_attendees.py +++ b/src/onegov/feriennet/views/occasion_attendees.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Private from onegov.activity import OccasionNeed, Volunteer from onegov.feriennet import FeriennetApp, _ @@ -18,10 +20,10 @@ permission=Private) def view_occasion_attendees( self: OccasionAttendeeCollection, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: - def occasion_volunteers(occasion: 'Occasion') -> tuple[Volunteer, ...]: + def occasion_volunteers(occasion: Occasion) -> tuple[Volunteer, ...]: return tuple(request.session.query(Volunteer).join(OccasionNeed). filter(OccasionNeed.occasion_id == occasion.id). filter(Volunteer.state == 'confirmed'). diff --git a/src/onegov/feriennet/views/payment_overrides.py b/src/onegov/feriennet/views/payment_overrides.py index fee099420c..cb5b6cabdf 100644 --- a/src/onegov/feriennet/views/payment_overrides.py +++ b/src/onegov/feriennet/views/payment_overrides.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import InvoiceCollection, InvoiceItem from onegov.core.security import Private from onegov.feriennet import FeriennetApp @@ -18,8 +20,8 @@ permission=Private) def sync_payments_and_reconcile( self: PaymentProviderCollection, - request: 'FeriennetRequest' -) -> 'Response': + request: FeriennetRequest +) -> Response: result = sync_payments(self, request) @@ -42,7 +44,7 @@ def sync_payments_and_reconcile( name='refund', request_method='POST', permission=Private) -def refund_and_reconcile(self: Payment, request: 'FeriennetRequest') -> None: +def refund_and_reconcile(self: Payment, request: FeriennetRequest) -> None: result = refund(self, request) for link in self.links: diff --git a/src/onegov/feriennet/views/period.py b/src/onegov/feriennet/views/period.py index bfc2ee0e8a..e3eff8a4d0 100644 --- a/src/onegov/feriennet/views/period.py +++ b/src/onegov/feriennet/views/period.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from onegov.activity import Period, PeriodCollection from onegov.core.security import Secret @@ -26,12 +28,12 @@ permission=Secret) def view_periods( self: PeriodCollection, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: layout = PeriodCollectionLayout(self, request) - def links(period: Period) -> 'Iterator[Link]': + def links(period: Period) -> Iterator[Link]: if period.active: yield Link( text=_('Deactivate'), @@ -161,7 +163,7 @@ def links(period: Period) -> 'Iterator[Link]': def is_date_range( range: tuple[date | None, date | None] -) -> 'TypeIs[tuple[date, date]]': +) -> TypeIs[tuple[date, date]]: return isinstance(range[0], date) and isinstance(range[1], date) @@ -173,9 +175,9 @@ def is_date_range( permission=Secret) def new_period( self: PeriodCollection, - request: 'FeriennetRequest', + request: FeriennetRequest, form: PeriodForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): assert form.title.data is not None @@ -218,9 +220,9 @@ def new_period( permission=Secret) def edit_period( self: Period, - request: 'FeriennetRequest', + request: FeriennetRequest, form: PeriodForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): form.populate_obj(self) @@ -249,7 +251,7 @@ def edit_period( model=Period, request_method='DELETE', permission=Secret) -def delete_period(self: Period, request: 'FeriennetRequest') -> None: +def delete_period(self: Period, request: FeriennetRequest) -> None: request.assert_valid_csrf_token() try: @@ -263,7 +265,7 @@ def delete_period(self: Period, request: 'FeriennetRequest') -> None: _('The period was deleted successfully')) @request.after - def redirect_intercooler(response: 'Response') -> None: + def redirect_intercooler(response: Response) -> None: response.headers.add( 'X-IC-Redirect', request.class_link(PeriodCollection)) @@ -273,7 +275,7 @@ def redirect_intercooler(response: 'Response') -> None: request_method='POST', name='activate', permission=Secret) -def activate_period(self: Period, request: 'FeriennetRequest') -> None: +def activate_period(self: Period, request: FeriennetRequest) -> None: request.assert_valid_csrf_token() self.activate() @@ -281,7 +283,7 @@ def activate_period(self: Period, request: 'FeriennetRequest') -> None: request.success(_('The period was activated successfully')) @request.after - def redirect_intercooler(response: 'Response') -> None: + def redirect_intercooler(response: Response) -> None: response.headers.add( 'X-IC-Redirect', request.class_link(PeriodCollection)) @@ -291,7 +293,7 @@ def redirect_intercooler(response: 'Response') -> None: request_method='POST', name='deactivate', permission=Secret) -def deactivate_period(self: Period, request: 'FeriennetRequest') -> None: +def deactivate_period(self: Period, request: FeriennetRequest) -> None: request.assert_valid_csrf_token() self.deactivate() @@ -299,7 +301,7 @@ def deactivate_period(self: Period, request: 'FeriennetRequest') -> None: request.success(_('The period was deactivated successfully')) @request.after - def redirect_intercooler(response: 'Response') -> None: + def redirect_intercooler(response: Response) -> None: response.headers.add( 'X-IC-Redirect', request.class_link(PeriodCollection)) @@ -309,7 +311,7 @@ def redirect_intercooler(response: 'Response') -> None: request_method='POST', name='archive', permission=Secret) -def archive_period(self: Period, request: 'FeriennetRequest') -> None: +def archive_period(self: Period, request: FeriennetRequest) -> None: request.assert_valid_csrf_token() self.archive() @@ -317,6 +319,6 @@ def archive_period(self: Period, request: 'FeriennetRequest') -> None: request.success(_('The period was archived successfully')) @request.after - def redirect_intercooler(response: 'Response') -> None: + def redirect_intercooler(response: Response) -> None: response.headers.add( 'X-IC-Redirect', request.class_link(PeriodCollection)) diff --git a/src/onegov/feriennet/views/settings.py b/src/onegov/feriennet/views/settings.py index 45f8e10bf0..106c83a225 100644 --- a/src/onegov/feriennet/views/settings.py +++ b/src/onegov/feriennet/views/settings.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from markupsafe import Markup from onegov.core.security import Secret from onegov.feriennet import _ @@ -34,7 +36,7 @@ class FeriennetSettingsForm(Form): - request: 'FeriennetRequest' + request: FeriennetRequest bank_qr_bill = BooleanField( label=_('QR-Bill'), @@ -288,7 +290,7 @@ def populate_obj(self, obj: Organisation) -> None: # type:ignore[override] icon='fa-child') def custom_handle_settings( self: Organisation, - request: 'FeriennetRequest', + request: FeriennetRequest, form: FeriennetSettingsForm -) -> 'RenderData | Response': +) -> RenderData | Response: return handle_generic_settings(self, request, form, _('Feriennet')) diff --git a/src/onegov/feriennet/views/shared.py b/src/onegov/feriennet/views/shared.py index 706d480020..a890bee616 100644 --- a/src/onegov/feriennet/views/shared.py +++ b/src/onegov/feriennet/views/shared.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.user import User, UserCollection from sqlalchemy import func @@ -7,7 +9,7 @@ from onegov.feriennet.request import FeriennetRequest -def users_for_select_element(request: 'FeriennetRequest') -> tuple[User, ...]: +def users_for_select_element(request: FeriennetRequest) -> tuple[User, ...]: u = UserCollection(request.session).query() u = u.with_entities(User.id, User.username, User.title, User.realname) u = u.order_by(func.lower(User.title)) diff --git a/src/onegov/feriennet/views/userlinks.py b/src/onegov/feriennet/views/userlinks.py index 7cf9b936b9..d045d55a56 100644 --- a/src/onegov/feriennet/views/userlinks.py +++ b/src/onegov/feriennet/views/userlinks.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.activity import Attendee, AttendeeCollection from onegov.activity import BookingCollection from onegov.feriennet import FeriennetApp, _ @@ -16,7 +18,7 @@ @FeriennetApp.userlinks() -def activity_links(request: 'FeriennetRequest', user: 'User') -> LinkGroup: +def activity_links(request: FeriennetRequest, user: User) -> LinkGroup: activities: Query[tuple[str, str]] = ( VacationActivityCollection( session=request.session, @@ -44,7 +46,7 @@ def activity_links(request: 'FeriennetRequest', user: 'User') -> LinkGroup: @FeriennetApp.userlinks() -def attendee_links(request: 'FeriennetRequest', user: 'User') -> LinkGroup: +def attendee_links(request: FeriennetRequest, user: User) -> LinkGroup: attendees: Query[tuple[UUID, str]] = ( AttendeeCollection(request.session).query() .filter_by(username=user.username) @@ -66,7 +68,7 @@ def attendee_links(request: 'FeriennetRequest', user: 'User') -> LinkGroup: @FeriennetApp.userlinks() -def booking_links(request: 'FeriennetRequest', user: 'User') -> LinkGroup: +def booking_links(request: FeriennetRequest, user: User) -> LinkGroup: return LinkGroup( title=_('Bookings'), links=[ @@ -82,7 +84,7 @@ def booking_links(request: 'FeriennetRequest', user: 'User') -> LinkGroup: @FeriennetApp.userlinks() -def billing_links(request: 'FeriennetRequest', user: 'User') -> LinkGroup: +def billing_links(request: FeriennetRequest, user: User) -> LinkGroup: return LinkGroup( title=_('Billing'), links=[ diff --git a/src/onegov/feriennet/views/userprofile.py b/src/onegov/feriennet/views/userprofile.py index 274e6a4250..bf16d7c547 100644 --- a/src/onegov/feriennet/views/userprofile.py +++ b/src/onegov/feriennet/views/userprofile.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Personal from onegov.feriennet import FeriennetApp from onegov.feriennet.forms import UserProfileForm @@ -17,7 +19,7 @@ permission=Personal, form=UserProfileForm) def handle_custom_user_profile( self: Organisation, - request: 'FeriennetRequest', + request: FeriennetRequest, form: UserProfileForm -) -> 'RenderData | Response': +) -> RenderData | Response: return handle_user_profile(self, request, form) diff --git a/src/onegov/feriennet/views/volunteer.py b/src/onegov/feriennet/views/volunteer.py index f4500d3384..a8b6403681 100644 --- a/src/onegov/feriennet/views/volunteer.py +++ b/src/onegov/feriennet/views/volunteer.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from itertools import groupby from onegov.activity import Volunteer, VolunteerCollection from onegov.core.security import Public, Secret @@ -28,15 +30,15 @@ permission=Secret) def view_volunteers( self: VolunteerCollection, - request: 'FeriennetRequest' -) -> 'RenderData': + request: FeriennetRequest +) -> RenderData: layout = VolunteerLayout(self, request) def grouped( - records: 'Iterable[ReportRow]', + records: Iterable[ReportRow], name: str - ) -> tuple[tuple['ReportRow', ...], ...]: + ) -> tuple[tuple[ReportRow, ...], ...]: return tuple( tuple(g) for k, g in groupby(records, key=attrgetter(name))) @@ -47,7 +49,7 @@ def grouped( else: has_needs = False - def state_change(record: 'ReportRow', state: str) -> str: + def state_change(record: ReportRow, state: str) -> str: assert record.volunteer_id is not None url = request.class_link( Volunteer, name=state, variables={'id': record.volunteer_id.hex}) @@ -75,7 +77,7 @@ def activity_link(activity_name: str) -> str: permission=Secret, name='open', request_method='POST') -def handle_open(self: Volunteer, request: 'FeriennetRequest') -> 'Response': +def handle_open(self: Volunteer, request: FeriennetRequest) -> Response: request.assert_valid_csrf_token() self.state = 'open' @@ -90,8 +92,8 @@ def handle_open(self: Volunteer, request: 'FeriennetRequest') -> 'Response': request_method='POST') def handle_contacted( self: Volunteer, - request: 'FeriennetRequest' -) -> 'Response': + request: FeriennetRequest +) -> Response: request.assert_valid_csrf_token() self.state = 'contacted' @@ -107,8 +109,8 @@ def handle_contacted( request_method='POST') def handle_confirmed( self: Volunteer, - request: 'FeriennetRequest' -) -> 'Response': + request: FeriennetRequest +) -> Response: request.assert_valid_csrf_token() self.state = 'confirmed' @@ -122,7 +124,7 @@ def handle_confirmed( permission=Secret, name='remove', request_method='POST') -def handle_remove(self: Volunteer, request: 'FeriennetRequest') -> 'Response': +def handle_remove(self: Volunteer, request: FeriennetRequest) -> Response: request.assert_valid_csrf_token() request.session.delete(self) @@ -133,7 +135,7 @@ def handle_remove(self: Volunteer, request: 'FeriennetRequest') -> 'Response': # Public, even though this is personal data -> the storage is limited to the # current browser session, which is separated from other users @FeriennetApp.json(model=VolunteerCart, permission=Public) -def view_cart(self: VolunteerCart, request: 'FeriennetRequest') -> 'JSON_ro': +def view_cart(self: VolunteerCart, request: FeriennetRequest) -> JSON_ro: return list(self.for_frontend(DefaultLayout(self, request))) @@ -143,8 +145,8 @@ def view_cart(self: VolunteerCart, request: 'FeriennetRequest') -> 'JSON_ro': request_method='POST') def execute_cart_action( self: VolunteerCartAction, - request: 'FeriennetRequest' -) -> 'JSON_ro': + request: FeriennetRequest +) -> JSON_ro: # FIXME: Despite the reasons listed below we should try to do better # @@ -165,9 +167,9 @@ def execute_cart_action( name='submit') def submit_volunteer( self: VolunteerCart, - request: 'FeriennetRequest', + request: FeriennetRequest, form: VolunteerForm -) -> 'RenderData': +) -> RenderData: layout = VolunteerFormLayout(self, request) request.include('volunteer-cart') diff --git a/src/onegov/file/__init__.py b/src/onegov/file/__init__.py index 8e8118be11..24f581eabb 100644 --- a/src/onegov/file/__init__.py +++ b/src/onegov/file/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.file') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/file/attachments.py b/src/onegov/file/attachments.py index cf2def02cb..daafb12f6c 100644 --- a/src/onegov/file/attachments.py +++ b/src/onegov/file/attachments.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import pdftotext # type:ignore from depot.fields.upload import UploadedFile @@ -40,7 +42,7 @@ def get_svg_size_or_default(content: IO[bytes]) -> tuple[str, str]: def strip_exif_and_limit_and_store_image_size( - file: 'ProcessedUploadedFile', + file: ProcessedUploadedFile, content: IO[bytes], content_type: str | None ) -> IO[bytes] | None: @@ -99,7 +101,7 @@ def strip_exif_and_limit_and_store_image_size( def store_checksum( - file: 'ProcessedUploadedFile', + file: ProcessedUploadedFile, content: IO[bytes], content_type: str | None ) -> None: @@ -108,7 +110,7 @@ def store_checksum( def sanitize_svg_images( - file: 'ProcessedUploadedFile', + file: ProcessedUploadedFile, content: IO[bytes], content_type: str | None ) -> IO[bytes]: @@ -121,7 +123,7 @@ def sanitize_svg_images( def store_extract_and_pages( - file: 'ProcessedUploadedFile', + file: ProcessedUploadedFile, content: IO[bytes], content_type: str | None ) -> None: @@ -146,7 +148,7 @@ class ProcessedUploadedFile(UploadedFile): def process_content( self, - content: '_FileContent', + content: _FileContent, filename: str | None = None, content_type: str | None = None ) -> None: diff --git a/src/onegov/file/collection.py b/src/onegov/file/collection.py index 89bb52b368..0c8063b8e1 100644 --- a/src/onegov/file/collection.py +++ b/src/onegov/file/collection.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import timedelta from depot.io.utils import file_from_content from onegov.file.models import File, FileSet @@ -38,8 +40,8 @@ class FileCollection(Generic[FileT]): @overload def __init__( - self: 'FileCollection[File]', - session: 'Session', + self: FileCollection[File], + session: Session, type: Literal['*', 'generic'] = '*', allow_duplicates: bool = True ) -> None: ... @@ -47,14 +49,14 @@ def __init__( @overload def __init__( self, - session: 'Session', + session: Session, type: str, allow_duplicates: bool = True ) -> None: ... def __init__( self, - session: 'Session', + session: Session, type: str = '*', allow_duplicates: bool = True ) -> None: @@ -62,7 +64,7 @@ def __init__( self.type = type self.allow_duplicates = allow_duplicates - def query(self) -> 'Query[FileT]': + def query(self) -> Query[FileT]: if self.type != '*': model_class = File.get_polymorphic_class(self.type, File) @@ -85,8 +87,8 @@ def add( content: bytes | IO[bytes], note: str | None = None, published: bool = True, - publish_date: 'datetime | None' = None, - publish_end_date: 'datetime | None' = None + publish_date: datetime | None = None, + publish_end_date: datetime | None = None ) -> FileT: """ Adds a file with the given filename. The content maybe either in bytes or a file object. @@ -134,8 +136,8 @@ def delete(self, file: File) -> None: def no_longer_published_files( self, - horizon: 'datetime' - ) -> 'Query[FileT]': + horizon: datetime + ) -> Query[FileT]: """ Returns a query of files where the publishing end date has expired. """ return self.query().filter(and_( @@ -143,7 +145,7 @@ def no_longer_published_files( File.publish_end_date < horizon )) - def publishable_files(self, horizon: 'datetime') -> 'Query[FileT]': + def publishable_files(self, horizon: datetime) -> Query[FileT]: """ Returns a query of files which may be published. """ return self.query().filter(and_( @@ -155,7 +157,7 @@ def publishable_files(self, horizon: 'datetime') -> 'Query[FileT]': ) )) - def publish_files(self, horizon: 'datetime | None' = None) -> None: + def publish_files(self, horizon: datetime | None = None) -> None: """ Publishes unpublished files with a publish date older than the given horizon. @@ -183,7 +185,7 @@ def by_id(self, file_id: str) -> FileT | None: return self.query().filter(File.id == file_id).first() - def by_filename(self, filename: str) -> 'Query[FileT]': + def by_filename(self, filename: str) -> Query[FileT]: """ Returns a query that matches the files with the given filename. Be aware that there may be multiple files with the same filename! @@ -191,14 +193,14 @@ def by_filename(self, filename: str) -> 'Query[FileT]': """ return self.query().filter(File.name == filename) - def by_checksum(self, checksum: str) -> 'Query[FileT]': + def by_checksum(self, checksum: str) -> Query[FileT]: """ Returns a query that matches the given checksum (may be more than one record). """ return self.query().filter(File.checksum == checksum) - def by_content(self, content: bytes | IO[bytes]) -> 'Query[FileT]': + def by_content(self, content: bytes | IO[bytes]) -> Query[FileT]: """ Returns a query that matches the given content (may be more than one record). @@ -225,7 +227,7 @@ def by_content(self, content: bytes | IO[bytes]) -> 'Query[FileT]': File.signature_metadata['old_digest'].astext == sha )) - def by_content_type(self, content_type: str) -> 'Query[FileT]': + def by_content_type(self, content_type: str) -> Query[FileT]: """ Returns a query that matches the given MIME content type (may be more than one record). @@ -237,7 +239,7 @@ def by_content_type(self, content_type: str) -> 'Query[FileT]': ) ) - def by_signature_digest(self, digest: str) -> 'Query[FileT]': + def by_signature_digest(self, digest: str) -> Query[FileT]: """ Returns a query that matches the given digest in the signature metadata. In other words, given a digest this function will find signed files that match the digest - either before or after signing. @@ -262,7 +264,7 @@ def by_signature_digest(self, digest: str) -> 'Query[FileT]': def locate_signature_metadata( self, digest: str - ) -> 'SignatureMetadata | None': + ) -> SignatureMetadata | None: """ Looks for the given digest in the files table - if that doesn't work it will go through the audit trail (i.e. the chat messages) and see if the digest can be found there. @@ -299,19 +301,19 @@ class FileSetCollection(Generic[FileSetT]): @overload def __init__( - self: 'FileSetCollection[FileSet]', - session: 'Session', + self: FileSetCollection[FileSet], + session: Session, type: Literal['*', 'generic'] = '*' ) -> None: ... @overload - def __init__(self, session: 'Session', type: str) -> None: ... + def __init__(self, session: Session, type: str) -> None: ... - def __init__(self, session: 'Session', type: str = '*') -> None: + def __init__(self, session: Session, type: str = '*') -> None: self.session = session self.type = type - def query(self) -> 'Query[FileSetT]': + def query(self) -> Query[FileSetT]: if self.type != '*': model_class = FileSet.get_polymorphic_class(self.type, FileSet) diff --git a/src/onegov/file/errors.py b/src/onegov/file/errors.py index 5dfcad2620..65de8acc6b 100644 --- a/src/onegov/file/errors.py +++ b/src/onegov/file/errors.py @@ -1,10 +1,12 @@ +from __future__ import annotations + from typing import TYPE_CHECKING if TYPE_CHECKING: from onegov.file import File class AlreadySignedError(RuntimeError): - def __init__(self, file: 'File'): + def __init__(self, file: File): super().__init__(f'File {file.id} has already been signed') diff --git a/src/onegov/file/filters.py b/src/onegov/file/filters.py index 3c61c06593..62c97c3795 100644 --- a/src/onegov/file/filters.py +++ b/src/onegov/file/filters.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os import shlex import logging @@ -32,10 +34,10 @@ class ConditionalFilter(FileFilter): def __init__(self, filter: FileFilter): self.filter = filter - def meets_condition(self, uploaded_file: 'UploadedFile') -> bool: + def meets_condition(self, uploaded_file: UploadedFile) -> bool: raise NotImplementedError - def on_save(self, uploaded_file: 'UploadedFile') -> None: + def on_save(self, uploaded_file: UploadedFile) -> None: if self.meets_condition(uploaded_file): self.filter.on_save(uploaded_file) @@ -46,7 +48,7 @@ class OnlyIfImage(ConditionalFilter): """ - def meets_condition(self, uploaded_file: 'UploadedFile') -> bool: + def meets_condition(self, uploaded_file: UploadedFile) -> bool: return uploaded_file.content_type in IMAGE_MIME_TYPES @@ -56,7 +58,7 @@ class OnlyIfPDF(ConditionalFilter): """ - def meets_condition(self, uploaded_file: 'UploadedFile') -> bool: + def meets_condition(self, uploaded_file: UploadedFile) -> bool: return uploaded_file.content_type == 'application/pdf' @@ -104,7 +106,7 @@ def generate_thumbnail( def store_thumbnail( self, - uploaded_file: 'UploadedFile', + uploaded_file: UploadedFile, fp: IO[bytes], thumbnail_size: tuple[str, str] | None = None, ) -> None: @@ -123,7 +125,7 @@ def store_thumbnail( 'size': thumbnail_size } - def on_save(self, uploaded_file: 'UploadedFile') -> None: + def on_save(self, uploaded_file: UploadedFile) -> None: close, fp = file_from_content(uploaded_file.original_content) thumbnail_fp, thumbnail_size = self.generate_thumbnail(fp) self.store_thumbnail(uploaded_file, thumbnail_fp, thumbnail_size) @@ -144,7 +146,7 @@ class WithPDFThumbnailFilter(WithThumbnailFilter): downscale_factor = 4 - def generate_preview(self, fp: 'SupportsRead[bytes]') -> BytesIO: + def generate_preview(self, fp: SupportsRead[bytes]) -> BytesIO: with TemporaryDirectory() as directory: path = Path(directory) @@ -195,7 +197,7 @@ def generate_preview(self, fp: 'SupportsRead[bytes]') -> BytesIO: def generate_thumbnail( self, - fp: 'SupportsRead[bytes]' + fp: SupportsRead[bytes] ) -> tuple[BytesIO, tuple[str, str]]: # FIXME: This is kinda slow. We should be able to render the # PDF directly at the thumbnail size. Maybe we should diff --git a/src/onegov/file/integration.py b/src/onegov/file/integration.py index 18ef82a39c..8ecb22356e 100644 --- a/src/onegov/file/integration.py +++ b/src/onegov/file/integration.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import morepath import os.path import shlex @@ -198,7 +200,7 @@ def bound_depot_id(self) -> str: return self.custom_depot_id or self.schema @property - def bound_depot(self) -> 'FileStorage | None': + def bound_depot(self) -> FileStorage | None: # FIXME: Do we actually care that the default depot is our depot? # One could imagine a separate thread which works on all # the file depots and gets the bound depot for each App @@ -348,7 +350,7 @@ def signing_service_id(self) -> str: return self.application_id.replace('/', '-') @property - def signing_service_config(self) -> 'SigningServiceConfig': + def signing_service_config(self) -> SigningServiceConfig: if not self.signing_services: raise RuntimeError('No signing service config path set') @@ -396,7 +398,7 @@ def temporary_depot( depot_storage_path: str | None = None, # FIXME: Remove this parameter **ignored: Any - ) -> 'Iterator[None]': + ) -> Iterator[None]: """ Temporarily use another depot. """ original_depot_backend = self.depot_backend @@ -429,12 +431,12 @@ def temporary_depot( @DepotApp.tween_factory(over=transaction_tween_factory) def configure_depot_tween_factory( app: DepotApp, - handler: 'Callable[[CoreRequest], Response]' -) -> 'Callable[[CoreRequest], Response]': + handler: Callable[[CoreRequest], Response] +) -> Callable[[CoreRequest], Response]: assert app.has_database_connection, 'This module requires a db backed app.' - def configure_depot_tween(request: 'CoreRequest') -> 'Response': + def configure_depot_tween(request: CoreRequest) -> Response: app.bind_depot() return handler(request) @@ -442,16 +444,16 @@ def configure_depot_tween(request: 'CoreRequest') -> 'Response': def render_depot_file( - file: 'StoredFile', - request: 'CoreRequest' -) -> 'Response': + file: StoredFile, + request: CoreRequest +) -> Response: return request.get_response( FileServeApp(file, cache_max_age=3600 * 24 * 7)) -def respond_with_alt_text(reference: File, request: 'CoreRequest') -> None: +def respond_with_alt_text(reference: File, request: CoreRequest) -> None: @request.after - def include_alt_text(response: 'Response') -> None: + def include_alt_text(response: Response) -> None: # HTTP headers are limited to ASCII, so we encode our result in # JSON before showing it response.headers.add('X-File-Note', json.dumps( @@ -461,21 +463,21 @@ def include_alt_text(response: 'Response') -> None: def respond_with_caching_header( reference: File, - request: 'CoreRequest' + request: CoreRequest ) -> None: if not reference.published: @request.after - def include_private_header(response: 'Response') -> None: + def include_private_header(response: Response) -> None: response.headers['Cache-Control'] = 'private' def respond_with_x_robots_tag_header( reference: File, - request: 'CoreRequest' + request: CoreRequest ) -> None: if getattr(reference, 'access', None) in ('secret', 'secret_mtan'): @request.after - def include_x_robots_tag_header(response: 'Response') -> None: + def include_x_robots_tag_header(response: Response) -> None: response.headers.add('X-Robots-Tag', 'noindex') @@ -485,7 +487,7 @@ def get_file(app: DepotApp, id: str) -> File | None: @DepotApp.view(model=File, render=render_depot_file, permission=Public) -def view_file(self: File, request: 'CoreRequest') -> 'StoredFile': +def view_file(self: File, request: CoreRequest) -> StoredFile: respond_with_alt_text(self, request) respond_with_caching_header(self, request) respond_with_x_robots_tag_header(self, request) @@ -500,8 +502,8 @@ def view_file(self: File, request: 'CoreRequest') -> 'StoredFile': render=render_depot_file) def view_thumbnail( self: File, - request: 'CoreRequest' -) -> 'StoredFile | Response': + request: CoreRequest +) -> StoredFile | Response: if request.view_name in ('small', 'medium'): size = request.view_name else: @@ -521,10 +523,10 @@ def view_thumbnail( @DepotApp.view(model=File, render=render_depot_file, permission=Public, request_method='HEAD') -def view_file_head(self: File, request: 'CoreRequest') -> 'StoredFile': +def view_file_head(self: File, request: CoreRequest) -> StoredFile: @request.after - def set_cache(response: 'Response') -> None: + def set_cache(response: Response) -> None: response.cache_control.max_age = 60 return view_file(self, request) @@ -538,11 +540,11 @@ def set_cache(response: 'Response') -> None: permission=Public, request_method='HEAD') def view_thumbnail_head( self: File, - request: 'CoreRequest' -) -> 'StoredFile | Response': + request: CoreRequest +) -> StoredFile | Response: @request.after - def set_cache(response: 'Response') -> None: + def set_cache(response: Response) -> None: response.cache_control.max_age = 60 return view_thumbnail(self, request) @@ -550,7 +552,7 @@ def set_cache(response: 'Response') -> None: @DepotApp.view(model=File, name='note', request_method='POST', permission=Private) -def handle_note_update(self: File, request: 'CoreRequest') -> None: +def handle_note_update(self: File, request: CoreRequest) -> None: request.assert_valid_csrf_token() note = request.POST.get('note') @@ -567,7 +569,7 @@ def handle_note_update(self: File, request: 'CoreRequest') -> None: @DepotApp.view(model=File, name='rename', request_method='POST', permission=Private) -def handle_rename(self: File, request: 'CoreRequest') -> None: +def handle_rename(self: File, request: CoreRequest) -> None: request.assert_valid_csrf_token() name = request.POST.get('name') @@ -587,7 +589,7 @@ def handle_rename(self: File, request: 'CoreRequest') -> None: @DepotApp.view(model=File, request_method='DELETE', permission=Private) -def delete_file(self: File, request: 'CoreRequest') -> None: +def delete_file(self: File, request: CoreRequest) -> None: """ Deletes the given file. By default the permission is ``Private``. An application using the framework can override this though. diff --git a/src/onegov/file/models/__init__.py b/src/onegov/file/models/__init__.py index 66d8b46db1..2502767050 100644 --- a/src/onegov/file/models/__init__.py +++ b/src/onegov/file/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.file.models.associated_files import ( AssociatedFiles, MultiAssociatedFiles) from onegov.file.models.file import File, SearchableFile diff --git a/src/onegov/file/models/associated_files.py b/src/onegov/file/models/associated_files.py index f618a526a3..1f995fa646 100644 --- a/src/onegov/file/models/associated_files.py +++ b/src/onegov/file/models/associated_files.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.abstract import associated from onegov.file.models.file import File diff --git a/src/onegov/file/models/file.py b/src/onegov/file/models/file.py index dddd7ef225..d921ab9554 100644 --- a/src/onegov/file/models/file.py +++ b/src/onegov/file/models/file.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import fcntl import json import sedate @@ -68,22 +70,22 @@ class UploadedFileField(UploadedFileFieldBase): def load_dialect_impl( self, - dialect: 'Dialect' - ) -> 'TypeEngine[UploadedFile]': + dialect: Dialect + ) -> TypeEngine[UploadedFile]: return dialect.type_descriptor(JSON()) def process_bind_param( # type:ignore[override] self, - value: 'UploadedFile | None', - dialect: 'Dialect' - ) -> 'UploadedFile | None': + value: UploadedFile | None, + dialect: Dialect + ) -> UploadedFile | None: return value if value else None def process_result_value( self, value: dict[str, Any] | None, - dialect: 'Dialect' - ) -> 'UploadedFile | None': + dialect: Dialect + ) -> UploadedFile | None: return self._upload_type(value) if value else None @@ -130,7 +132,7 @@ class File(Base, Associable, TimestampMixin): __tablename__ = 'files' #: the unique, public id of the file - id: 'Column[str]' = Column( + id: Column[str] = Column( Text, nullable=False, primary_key=True, @@ -138,16 +140,16 @@ class File(Base, Associable, TimestampMixin): ) #: the name of the file, incl. extension (not used for public links) - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: a short note about the file (for captions, other information) - note: 'Column[str | None]' = Column(Text, nullable=True) + note: Column[str | None] = Column(Text, nullable=True) #: the default order of files - order: 'Column[str]' = Column(Text, nullable=False) + order: Column[str] = Column(Text, nullable=False) #: true if published - published: 'Column[bool]' = Column(Boolean, nullable=False, default=True) + published: Column[bool] = Column(Boolean, nullable=False, default=True) #: the date after which this file will be made public - this controls #: the visibility of the object through the ``access`` @@ -156,19 +158,19 @@ class File(Base, Associable, TimestampMixin): #: To get a file published, be sure to call #: :meth:`onegov.file.collection.FileCollection.publish_files` once an #: hour through a cronjob (see :mod:`onegov.core.cronjobs`)! - publish_date: 'Column[datetime | None]' = Column( + publish_date: Column[datetime | None] = Column( UTCDateTime, nullable=True ) #: the date up to which the file is published - publish_end_date: 'Column[datetime | None]' = Column( + publish_end_date: Column[datetime | None] = Column( UTCDateTime, nullable=True ) #: true if marked for publication - publication: 'Column[bool]' = Column( + publication: Column[bool] = Column( Boolean, nullable=False, default=False @@ -179,7 +181,7 @@ class File(Base, Associable, TimestampMixin): #: (the file could be signed without this being true, but that would #: amount to a signature created outside of our platform, which is #: something we ignore) - signed: 'Column[bool]' = Column(Boolean, nullable=False, default=False) + signed: Column[bool] = Column(Boolean, nullable=False, default=False) #: the metadata of the signature - this should include the following #: data:: @@ -190,7 +192,7 @@ class File(Base, Associable, TimestampMixin): #: - timestamp: The time the document was signed in UTC #: - request_id: A unique identifier by the signing service #: - signature_metadata: 'Column[SignatureMetadata | None]' = deferred( + signature_metadata: Column[SignatureMetadata | None] = deferred( Column(JSON, nullable=True) ) @@ -200,7 +202,7 @@ class File(Base, Associable, TimestampMixin): #: #: not to be confused with the the actual filetype which is stored #: on the :attr:`reference`! - type: 'Column[str]' = Column( + type: Column[str] = Column( Text, nullable=False, default=lambda: 'generic' @@ -208,7 +210,7 @@ class File(Base, Associable, TimestampMixin): #: the reference to the actual file, uses depot to point to a file on #: the local file system or somewhere else (e.g. S3) - reference: '_UploadedFileColumn' = Column(UploadedFileField( # type:ignore + reference: _UploadedFileColumn = Column(UploadedFileField( # type:ignore upload_type=ProcessedUploadedFile, filters=[ OnlyIfImage( @@ -233,26 +235,26 @@ class File(Base, Associable, TimestampMixin): #: #: note, this is not meant to be cryptographically secure - this is #: strictly a check of file duplicates, not protection against tampering - checksum: 'Column[str | None]' = Column(Text, nullable=True, index=True) + checksum: Column[str | None] = Column(Text, nullable=True, index=True) #: the content of the given file as text, if it can be extracted #: (it is important that this column be loaded deferred by default, lest #: we load massive amounts of text on simple queries) - extract: 'Column[str | None]' = deferred(Column(Text, nullable=True)) + extract: Column[str | None] = deferred(Column(Text, nullable=True)) #: the languge of the file - language: 'Column[str | None]' = Column(Text, nullable=True) + language: Column[str | None] = Column(Text, nullable=True) #: statistics around the extract (number of pages, words, etc.) #: those are usually set during file upload (as some information is #: lost afterwards) - stats: 'Column[FileStats | None]' = deferred(Column(JSON, nullable=True)) + stats: Column[FileStats | None] = deferred(Column(JSON, nullable=True)) #: arbitrary additional meta data, which can be used by subclasses to #: store additional information using e.g. `meta_property` - meta: 'Column[dict[str, Any]]' = Column(JSON, nullable=False, default=dict) + meta: Column[dict[str, Any]] = Column(JSON, nullable=False, default=dict) - filesets: 'relationship[list[FileSet]]' = relationship( + filesets: relationship[list[FileSet]] = relationship( 'FileSet', secondary=file_to_set_associations, back_populates='files' @@ -268,7 +270,7 @@ class File(Base, Associable, TimestampMixin): ) @hybrid_property - def signature_timestamp(self) -> 'datetime | None': + def signature_timestamp(self) -> datetime | None: if self.signed: return sedate.replace_timezone( isodate.parse_datetime(self.signature_metadata['timestamp']), @@ -297,7 +299,7 @@ def signature_timestamp(cls): # then we would need to instantiate a DepotApp for testing # which could get annoying @observes('reference') - def reference_observer(self, reference: 'UploadedFile') -> None: + def reference_observer(self, reference: UploadedFile) -> None: if 'checksum' in self.reference: self.checksum = self.reference.pop('checksum') @@ -343,7 +345,7 @@ def claimed_extension(self) -> str: return extension_for_content_type( self.reference['content_type'], self.name) - def get_thumbnail_id(self, size: str) -> 'UploadedFile | None': + def get_thumbnail_id(self, size: str) -> UploadedFile | None: """ Returns the thumbnail id with the given size (e.g. 'small'). """ @@ -402,9 +404,9 @@ def _update_metadata(self, **options: Any) -> None: @contextmanager def metadata_lock( - metadata_path: 'StrPath', + metadata_path: StrPath, timeout: float = 0.0, -) -> 'Iterator[bool]': +) -> Iterator[bool]: """ Locks the metadata from a ``filedepot.io.local.LocalStoredFile``. Tries to acquire the lock repeatedly in a spin lock until timeout expires, it will return whether or not it managed to acquire the lock @@ -425,7 +427,7 @@ def metadata_lock( break -@event.listens_for(Session, 'after_commit') +@event.listens_for(Session, 'after_commit') # type:ignore[misc] def update_metadata_after_commit(session: Session) -> None: if 'pending_metadata_changes' not in session.info: return @@ -457,10 +459,10 @@ def update_metadata_after_commit(session: Session) -> None: del session.info['pending_metadata_changes'] -@event.listens_for(Session, 'after_soft_rollback') +@event.listens_for(Session, 'after_soft_rollback') # type:ignore[misc] def discard_metadata_on_rollback( session: Session, - previous_transaction: 'SessionTransaction' + previous_transaction: SessionTransaction ) -> None: if 'pending_metadata_changes' in session.info: del session.info['pending_metadata_changes'] diff --git a/src/onegov/file/models/file_message.py b/src/onegov/file/models/file_message.py index cc942c106c..74395eb85b 100644 --- a/src/onegov/file/models/file_message.py +++ b/src/onegov/file/models/file_message.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.chat import Message from sqlalchemy.orm import object_session @@ -13,7 +15,7 @@ class FileMessage(Message): } @classmethod - def log_signature(cls, file: 'File', signee: str) -> None: + def log_signature(cls, file: File, signee: str) -> None: cls.bound_messages(object_session(file)).add( channel_id=file.id, owner=signee, @@ -27,7 +29,7 @@ def log_signature(cls, file: 'File', signee: str) -> None: @classmethod def log_signed_file_removal( cls, - file: 'File', + file: File, username: str | None ) -> None: cls.bound_messages(object_session(file)).add( diff --git a/src/onegov/file/models/fileset.py b/src/onegov/file/models/fileset.py index d57b06455d..13b561ae5a 100644 --- a/src/onegov/file/models/fileset.py +++ b/src/onegov/file/models/fileset.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.crypto import random_token from onegov.core.orm import Base from onegov.core.orm.mixins import ContentMixin, TimestampMixin @@ -34,7 +36,7 @@ class FileSet(Base, ContentMixin, TimestampMixin): __tablename__ = 'filesets' #: the unique, public id of the fileset - id: 'Column[str]' = Column( + id: Column[str] = Column( Text, nullable=False, primary_key=True, @@ -42,7 +44,7 @@ class FileSet(Base, ContentMixin, TimestampMixin): ) #: the title of the fileset (not usable in url) - title: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) #: the type of the fileset, this can be used to create custom polymorphic #: subclasses. See ` None: def __get__( self, instance: None, - owner: type['HasFiles'] | None = None - ) -> 'Self': ... + owner: type[HasFiles] | None = None + ) -> Self: ... @overload def __get__( self, - instance: 'HasFiles', - owner: type['HasFiles'] | None = None + instance: HasFiles, + owner: type[HasFiles] | None = None ) -> File | None: ... def __get__( self, - instance: 'HasFiles | None', - owner: type['HasFiles'] | None = None - ) -> 'Self | File | None': + instance: HasFiles | None, + owner: type[HasFiles] | None = None + ) -> Self | File | None: if instance is None: return None @@ -75,7 +77,7 @@ def __get__( def __set__( self, - instance: 'HasFiles', + instance: HasFiles, value: tuple[bytes | IO[bytes], str | None] ) -> None: @@ -86,7 +88,7 @@ def __set__( file.reference = as_fileintent(content, filename) instance.files.append(file) - def __delete__(self, instance: 'HasFiles') -> None: + def __delete__(self, instance: HasFiles) -> None: for file in tuple(instance.files): if file.name == self.name: instance.files.remove(file) diff --git a/src/onegov/file/sign/__init__.py b/src/onegov/file/sign/__init__.py index a3434ab386..3c80558e9e 100644 --- a/src/onegov/file/sign/__init__.py +++ b/src/onegov/file/sign/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.file.sign.generic import SigningService from onegov.file.sign.swisscom_ais import SwisscomAIS diff --git a/src/onegov/file/sign/generic.py b/src/onegov/file/sign/generic.py index a26d1c94fe..52627b551c 100644 --- a/src/onegov/file/sign/generic.py +++ b/src/onegov/file/sign/generic.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os.path from contextlib import contextmanager, suppress @@ -19,7 +21,7 @@ def name(self) -> str: ... class SigningService: """ A generic interface for various file signing services. """ - registry: ClassVar[dict[str, type['SigningService']]] = {} + registry: ClassVar[dict[str, type[SigningService]]] = {} service_name: ClassVar[str] def __init_subclass__(cls, service_name: str, **kwargs: Any): @@ -29,7 +31,7 @@ def __init_subclass__(cls, service_name: str, **kwargs: Any): super().__init_subclass__(**kwargs) @staticmethod - def for_config(config: 'SigningServiceConfig') -> 'SigningService': + def for_config(config: SigningServiceConfig) -> SigningService: """ Spawns a service instance using the given config. """ return SigningService.registry[config['name']]( @@ -63,8 +65,8 @@ def __init__(self, user, password): def sign( self, - infile: 'SupportsRead[bytes]', - outfile: 'SupportsWrite[bytes]' + infile: SupportsRead[bytes], + outfile: SupportsWrite[bytes] ) -> str: """ Signs the input file and writes it to the given output file. @@ -105,8 +107,8 @@ def sign(self, infile, outfile, foo='bar') @contextmanager def materialise( self, - file: 'SupportsRead[bytes]' - ) -> 'Iterator[SupportsReadAndHasName]': + file: SupportsRead[bytes] + ) -> Iterator[SupportsReadAndHasName]: """ Takes the given file-like object and ensures that it exists somewhere on the disk during the lifetime of the context. diff --git a/src/onegov/file/sign/swisscom_ais.py b/src/onegov/file/sign/swisscom_ais.py index 01327b39f6..98919f8f7d 100644 --- a/src/onegov/file/sign/swisscom_ais.py +++ b/src/onegov/file/sign/swisscom_ais.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import io import os @@ -35,8 +37,8 @@ def __init__( def sign( self, - infile: 'SupportsRead[bytes]', - outfile: 'SupportsWrite[bytes]' + infile: SupportsRead[bytes], + outfile: SupportsWrite[bytes] ) -> str: if hasattr(infile, 'seek'): diff --git a/src/onegov/file/types.py b/src/onegov/file/types.py index 5a829e4fb8..c71b801f38 100644 --- a/src/onegov/file/types.py +++ b/src/onegov/file/types.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import TYPE_CHECKING if TYPE_CHECKING: from typing import Any diff --git a/src/onegov/file/upgrade.py b/src/onegov/file/upgrade.py index 9d28b07f59..6d0fe5b965 100644 --- a/src/onegov/file/upgrade.py +++ b/src/onegov/file/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + import multiprocessing from concurrent.futures import ThreadPoolExecutor @@ -32,14 +34,14 @@ @upgrade_task('Add checksum column') -def add_checksum_column(context: 'UpgradeContext') -> None: +def add_checksum_column(context: UpgradeContext) -> None: context.operations.add_column( 'files', Column('checksum', Text, nullable=True, index=True) ) @upgrade_task('Add image size 3') -def add_image_size(context: 'UpgradeContext') -> None: +def add_image_size(context: UpgradeContext) -> None: images: FileCollection[Any] = FileCollection(context.session, type='image') for image in images.query(): @@ -74,13 +76,13 @@ def add_image_size(context: 'UpgradeContext') -> None: @upgrade_task('Add files by type and name index') -def add_files_by_type_and_name_index(context: 'UpgradeContext') -> None: +def add_files_by_type_and_name_index(context: UpgradeContext) -> None: context.operations.create_index( 'files_by_type_and_name', 'files', ['type', 'name']) @upgrade_task('Migrate file metadata to JSONB') -def migrate_file_metadata_to_jsonb(context: 'UpgradeContext') -> None: +def migrate_file_metadata_to_jsonb(context: UpgradeContext) -> None: context.session.execute(""" ALTER TABLE files ALTER COLUMN reference @@ -99,7 +101,7 @@ def migrate_file_metadata_to_jsonb(context: 'UpgradeContext') -> None: @upgrade_task('Add thumbnails to PDFs') -def add_thumbnails_to_pdfs(context: 'UpgradeContext') -> None: +def add_thumbnails_to_pdfs(context: UpgradeContext) -> None: if not isinstance(context.app, DepotApp): return False # type:ignore[return-value] @@ -122,7 +124,7 @@ def add_thumbnails_to_pdfs(context: 'UpgradeContext') -> None: def chunks( size: int = max_workers - ) -> 'Iterator[list[tuple[File, StoredFile]]]': + ) -> Iterator[list[tuple[File, StoredFile]]]: while True: chunk = [] @@ -157,7 +159,7 @@ def chunks( @upgrade_task('Add publication dates') -def add_publication_dates(context: 'UpgradeContext') -> None: +def add_publication_dates(context: UpgradeContext) -> None: context.operations.add_column( 'files', Column('publish_date', UTCDateTime, nullable=True)) @@ -168,14 +170,14 @@ def add_publication_dates(context: 'UpgradeContext') -> None: @upgrade_task('Publication end dates') -def add_publication_end_dates(context: 'UpgradeContext') -> None: +def add_publication_end_dates(context: UpgradeContext) -> None: if not (context.has_column('files', 'publish_end_date')): context.operations.add_column( 'files', Column('publish_end_date', UTCDateTime, nullable=True)) @upgrade_task('Add signed property') -def add_signed_property(context: 'UpgradeContext') -> None: +def add_signed_property(context: UpgradeContext) -> None: context.add_column_with_defaults( table='files', column=Column('signed', Boolean, nullable=False), @@ -183,7 +185,7 @@ def add_signed_property(context: 'UpgradeContext') -> None: @upgrade_task('Reclassify office documents') -def reclassify_office_documents(context: 'UpgradeContext') -> None: +def reclassify_office_documents(context: UpgradeContext) -> None: if not isinstance(context.app, DepotApp): return False # type:ignore[return-value] @@ -201,7 +203,7 @@ def reclassify_office_documents(context: 'UpgradeContext') -> None: @upgrade_task('Add extract and pages column') -def add_extract_and_pages_column(context: 'UpgradeContext') -> None: +def add_extract_and_pages_column(context: UpgradeContext) -> None: context.operations.add_column( 'files', Column('extract', Text, nullable=True)) @@ -215,7 +217,7 @@ def add_extract_and_pages_column(context: 'UpgradeContext') -> None: # it along. Generally it's better to steer clear of using Models # inside upgrade tasks, it should generally use raw queries. @upgrade_task('Extract pdf text of existing files') -def extract_pdf_text_of_existing_files(context: 'UpgradeContext') -> None: +def extract_pdf_text_of_existing_files(context: UpgradeContext) -> None: pdfs = FileCollection(context.session).by_content_type('application/pdf') for pdf in pdfs: @@ -232,13 +234,13 @@ def extract_pdf_text_of_existing_files(context: 'UpgradeContext') -> None: @upgrade_task('Add signature_metadata column') -def add_signature_metadata_column(context: 'UpgradeContext') -> None: +def add_signature_metadata_column(context: UpgradeContext) -> None: context.operations.add_column( 'files', Column('signature_metadata', JSON, nullable=True)) @upgrade_task('Add stats column') -def add_stats_column(context: 'UpgradeContext') -> None: +def add_stats_column(context: UpgradeContext) -> None: context.operations.add_column( 'files', Column('stats', JSON, nullable=True)) @@ -269,7 +271,7 @@ def add_stats_column(context: 'UpgradeContext') -> None: @upgrade_task('Add publication column') -def add_publication_column(context: 'UpgradeContext') -> None: +def add_publication_column(context: UpgradeContext) -> None: if not context.has_column('files', 'publication'): context.operations.add_column( 'files', @@ -284,7 +286,7 @@ def add_publication_column(context: 'UpgradeContext') -> None: @upgrade_task('Add language column') -def add_language_column(context: 'UpgradeContext') -> None: +def add_language_column(context: UpgradeContext) -> None: if not context.has_column('files', 'language'): context.operations.add_column( 'files', @@ -294,7 +296,7 @@ def add_language_column(context: 'UpgradeContext') -> None: @upgrade_task('Make file models polymorphic type non-nullable') def make_file_models_polymorphic_type_non_nullable( - context: 'UpgradeContext' + context: UpgradeContext ) -> None: for table in ('files', 'filesets'): if context.has_table(table): @@ -306,7 +308,7 @@ def make_file_models_polymorphic_type_non_nullable( @upgrade_task('Add meta column') -def add_meta_column(context: 'UpgradeContext') -> None: +def add_meta_column(context: UpgradeContext) -> None: context.operations.add_column( 'files', Column( 'meta', diff --git a/src/onegov/file/utils.py b/src/onegov/file/utils.py index 17070b8a65..f9daa6a386 100644 --- a/src/onegov/file/utils.py +++ b/src/onegov/file/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import hashlib import magic import os @@ -17,7 +19,7 @@ from collections.abc import Iterator -def content_type_from_fileobj(fileobj: 'SupportsRead[bytes]') -> str: +def content_type_from_fileobj(fileobj: SupportsRead[bytes]) -> str: """ Gets the content type from a file obj. Depot has this as well, but it doesn't use python-magic. We use python-magic to be slower, but more accurate. @@ -130,7 +132,7 @@ def get_image_size(image: Image.Image) -> tuple[str, str]: def digest( - fileobj: 'SupportsRead[bytes]', + fileobj: SupportsRead[bytes], type: str = 'sha256', chunksize: int = 4096 ) -> str: @@ -179,7 +181,7 @@ def name_without_extension(name: str) -> str: @contextmanager -def current_dir(dir: 'StrOrBytesPath') -> 'Iterator[None]': +def current_dir(dir: StrOrBytesPath) -> Iterator[None]: previous = os.getcwd() os.chdir(dir) yield diff --git a/src/onegov/form/__init__.py b/src/onegov/form/__init__.py index 1855260c2b..9db7d71dfb 100644 --- a/src/onegov/form/__init__.py +++ b/src/onegov/form/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.form') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/form/collection.py b/src/onegov/form/collection.py index 8fe68b8d16..078de4632a 100644 --- a/src/onegov/form/collection.py +++ b/src/onegov/form/collection.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import warnings from datetime import datetime, timedelta @@ -48,19 +50,19 @@ class FormCollection: """ Manages a collection of forms and form-submissions. """ - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session @property - def definitions(self) -> 'FormDefinitionCollection': + def definitions(self) -> FormDefinitionCollection: return FormDefinitionCollection(self.session) @property - def submissions(self) -> 'FormSubmissionCollection': + def submissions(self) -> FormSubmissionCollection: return FormSubmissionCollection(self.session) @property - def registration_windows(self) -> 'FormRegistrationWindowCollection': + def registration_windows(self) -> FormRegistrationWindowCollection: return FormRegistrationWindowCollection(self.session) @overload @@ -68,20 +70,20 @@ def scoped_submissions( self, name: str, ensure_existance: Literal[False] - ) -> 'FormSubmissionCollection': ... + ) -> FormSubmissionCollection: ... @overload def scoped_submissions( self, name: str, ensure_existance: bool = True - ) -> 'FormSubmissionCollection | None': ... + ) -> FormSubmissionCollection | None: ... def scoped_submissions( self, name: str, ensure_existance: bool = True - ) -> 'FormSubmissionCollection | None': + ) -> FormSubmissionCollection | None: if not ensure_existance or self.definitions.by_name(name): return FormSubmissionCollection(self.session, name) return None @@ -91,7 +93,7 @@ def scoped_submissions( # But we have to wait until this feature is available def get_definitions_with_submission_count( self - ) -> 'Iterator[FormDefinition]': + ) -> Iterator[FormDefinition]: """ Returns all form definitions and the number of submissions belonging to those definitions, in a single query. @@ -122,10 +124,10 @@ def get_definitions_with_submission_count( class FormDefinitionCollection: """ Manages a collection of forms. """ - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session - def query(self) -> 'Query[FormDefinition]': + def query(self) -> Query[FormDefinition]: return self.session.query(FormDefinition) def add( @@ -136,7 +138,7 @@ def add( meta: dict[str, Any] | None = None, content: dict[str, Any] | None = None, name: str | None = None, - payment_method: 'PaymentMethod' = 'manual', + payment_method: PaymentMethod = 'manual', pick_up: str | None = None ) -> FormDefinition: """ Add the given form to the database. """ @@ -165,8 +167,8 @@ def delete( name: str, with_submissions: bool = False, with_registration_windows: bool = False, - handle_submissions: 'SubmissionHandler | None' = None, - handle_registration_windows: 'RegistrationWindowHandler | None' = None, + handle_submissions: SubmissionHandler | None = None, + handle_registration_windows: RegistrationWindowHandler | None = None, ) -> None: """ Delete the given form. Only possible if there are no submissions associated with it, or if ``with_submissions`` is True. @@ -221,11 +223,11 @@ def by_name(self, name: str) -> FormDefinition | None: class FormSubmissionCollection: """ Manages a collection of submissions. """ - def __init__(self, session: 'Session', name: str | None = None): + def __init__(self, session: Session, name: str | None = None): self.session = session self.name = name - def query(self) -> 'Query[FormSubmission]': + def query(self) -> Query[FormSubmission]: query = self.session.query(FormSubmission) if self.name is not None: @@ -236,10 +238,10 @@ def query(self) -> 'Query[FormSubmission]': def add( self, name: str | None, - form: 'Form', - state: 'SubmissionState', + form: Form, + state: SubmissionState, id: UUID | None = None, - payment_method: 'PaymentMethod | None' = None, + payment_method: PaymentMethod | None = None, minimum_price_total: float | None = None, meta: dict[str, Any] | None = None, email: str | None = None, @@ -330,10 +332,10 @@ def add( def add_external( self, - form: 'Form', - state: 'SubmissionState', + form: Form, + state: SubmissionState, id: UUID | None = None, - payment_method: 'PaymentMethod | None' = None, + payment_method: PaymentMethod | None = None, minimum_price_total: float | None = None, meta: dict[str, Any] | None = None, email: str | None = None @@ -386,8 +388,8 @@ def complete_submission(self, submission: FormSubmission) -> None: def update( self, submission: FormSubmission, - form: 'Form', - exclude: 'Collection[str] | None ' = None + form: Form, + exclude: Collection[str] | None = None ) -> None: """ Takes a submission and a form and updates the submission data as well as the files stored in a separate table. @@ -557,7 +559,7 @@ def remove_old_pending_submissions( for submission in submissions: self.session.delete(submission) - def by_state(self, state: 'SubmissionState') -> 'Query[FormSubmission]': + def by_state(self, state: SubmissionState) -> Query[FormSubmission]: return self.query().filter(FormSubmission.state == state) # FIXME: Why are we returning a list here? @@ -568,7 +570,7 @@ def by_name(self, name: str) -> list[FormSubmission]: def by_id( self, id: UUID, - state: 'SubmissionState | None' = None, + state: SubmissionState | None = None, current_only: bool = False ) -> FormSubmission | None: """ Return the submission by id. @@ -600,7 +602,7 @@ class FormRegistrationWindowCollection( GenericCollection[FormRegistrationWindow] ): - def __init__(self, session: 'Session', name: str | None = None): + def __init__(self, session: Session, name: str | None = None): super().__init__(session) self.name = name @@ -608,7 +610,7 @@ def __init__(self, session: 'Session', name: str | None = None): def model_class(self) -> type[FormRegistrationWindow]: return FormRegistrationWindow - def query(self) -> 'Query[FormRegistrationWindow]': + def query(self) -> Query[FormRegistrationWindow]: query = super().query() if self.name: @@ -620,10 +622,10 @@ def query(self) -> 'Query[FormRegistrationWindow]': class SurveyDefinitionCollection: """ Manages a collection of surveys. """ - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session - def query(self) -> 'Query[SurveyDefinition]': + def query(self) -> Query[SurveyDefinition]: return self.session.query(SurveyDefinition) def add( @@ -659,8 +661,8 @@ def delete( self, name: str, with_submission_windows: bool = False, - handle_submissions: 'SurveySubmissionHandler | None' = None, - handle_submission_windows: 'SubmissionWindowHandler | None' = None, + handle_submissions: SurveySubmissionHandler | None = None, + handle_submission_windows: SubmissionWindowHandler | None = None, ) -> None: """ Delete the given form. Only possible if there are no submissions associated with it, or if ``with_submissions`` is True. @@ -701,11 +703,11 @@ def by_name(self, name: str) -> SurveyDefinition | None: class SurveySubmissionCollection: """ Manages a collection of survey submissions. """ - def __init__(self, session: 'Session', name: str | None = None): + def __init__(self, session: Session, name: str | None = None): self.session = session self.name = name - def query(self) -> 'Query[SurveySubmission]': + def query(self) -> Query[SurveySubmission]: query = self.session.query(SurveySubmission) if self.name is not None: @@ -716,7 +718,7 @@ def query(self) -> 'Query[SurveySubmission]': def add( self, name: str | None, - form: 'Form', + form: Form, submission_window: SurveySubmissionWindow | None = None, id: UUID | None = None, meta: dict[str, Any] | None = None, @@ -773,8 +775,8 @@ def add( def update( self, submission: SurveySubmission, - form: 'Form', - exclude: 'Collection[str] | None ' = None + form: Form, + exclude: Collection[str] | None = None ) -> None: """ Takes a submission and a survey and updates the submission data as well as the files stored in a separate table. @@ -828,7 +830,7 @@ class SurveySubmissionWindowCollection( GenericCollection[SurveySubmissionWindow] ): - def __init__(self, session: 'Session', name: str | None = None): + def __init__(self, session: Session, name: str | None = None): super().__init__(session) self.name = name @@ -836,7 +838,7 @@ def __init__(self, session: 'Session', name: str | None = None): def model_class(self) -> type[SurveySubmissionWindow]: return SurveySubmissionWindow - def query(self) -> 'Query[SurveySubmissionWindow]': + def query(self) -> Query[SurveySubmissionWindow]: query = super().query() if self.name: @@ -848,7 +850,7 @@ def query(self) -> 'Query[SurveySubmissionWindow]': class SurveyCollection: """ Manages a collection of surveys and survey-submissions. """ - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session @property @@ -891,7 +893,7 @@ def scoped_submissions( # But we have to wait until this feature is available def get_definitions_with_submission_count( self - ) -> 'Iterator[FormDefinition]': + ) -> Iterator[FormDefinition]: """ Returns all form definitions and the number of submissions belonging to those definitions, in a single query. diff --git a/src/onegov/form/core.py b/src/onegov/form/core.py index 2abbdb4273..8e3bab4fa0 100644 --- a/src/onegov/form/core.py +++ b/src/onegov/form/core.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import weakref from collections import OrderedDict @@ -123,7 +125,7 @@ class MyForm(Form): stamps = IntegerRangeField( 'No. Stamps', range=range(0, 30), - pricing={range(0, 30): (0.85, 'CHF')} + pricing={range(0, 30): (1.00, 'CHF')} ) delivery = RadioField('Delivery', choices=[ @@ -146,7 +148,7 @@ class MyForm(Form): """ - fieldsets: list['Fieldset'] + fieldsets: list[Fieldset] hidden_fields: set[str] if TYPE_CHECKING: @@ -154,7 +156,7 @@ class MyForm(Form): # meta, since that is where data like that is supposed to live # but it'll be a pain to find everywhere we access request # through anything other than meta. - request: 'CoreRequest' + request: CoreRequest model: Any # NOTE: While action isn't guaranteed to be set, it almost always will @@ -164,13 +166,13 @@ class MyForm(Form): def __init__( self, - formdata: 'MultiDict[str, Any] | None' = None, + formdata: MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, - extra_filters: 'Mapping[str, Sequence[Any]] | None' = None, + extra_filters: Mapping[str, Sequence[Any]] | None = None, **kwargs: Any ): @@ -203,7 +205,7 @@ def __init__( self.hidden_fields = set() @classmethod - def clone(cls) -> type['Self']: + def clone(cls) -> type[Self]: """ Creates an independent copy of the form class. The fields of the so called class may be manipulated without affecting @@ -222,7 +224,7 @@ class ClonedForm(cls): # type:ignore return ClonedForm - def process_fieldset(self) -> 'Iterator[None]': + def process_fieldset(self) -> Iterator[None]: """ Processes the fieldset parameter on the fields, which puts fields into fieldsets. @@ -267,7 +269,7 @@ def process_fieldset(self) -> 'Iterator[None]': fields=(self._fields[field_id] for _, field_id in fields) )) - def process_depends_on(self) -> 'Iterator[None]': + def process_depends_on(self) -> Iterator[None]: """ Processes the depends_on parameter on the fields, which adds the ability to have fields depend on values of other fields. @@ -340,7 +342,7 @@ def process_depends_on(self) -> 'Iterator[None]': field.depends_on.html_data(self._prefix) ) - def process_pricing(self) -> 'Iterator[None]': + def process_pricing(self) -> Iterator[None]: """ Processes the pricing parameter on the fields, which adds the ability to have fields associated with a price. @@ -366,7 +368,7 @@ def process_pricing(self) -> 'Iterator[None]': for field_id, pricing in pricings.items(): self._fields[field_id].pricing = pricing - def render_display(self, field: 'Field') -> Markup | None: + def render_display(self, field: Field) -> Markup | None: """ Renders the given field for display (no input). May be overwritten by descendants to return different html, or to return None. @@ -398,7 +400,7 @@ def is_visible_through_dependencies(self, field_id: str) -> bool: for d in depends_on.dependencies ) - def is_hidden(self, field: 'Field') -> bool: + def is_hidden(self, field: Field) -> bool: """ True if the given field should be hidden. The effect of this is left to the application (it might not render the field, or add a class which hides the field). @@ -406,11 +408,11 @@ class which hides the field). """ return field.id in self.hidden_fields - def hide(self, field: 'Field') -> None: + def hide(self, field: Field) -> None: """ Marks the given field as hidden. """ self.hidden_fields.add(field.id) - def show(self, field: 'Field') -> None: + def show(self, field: Field) -> None: """ Marks the given field as visibile. """ self.hidden_fields.discard(field.id) @@ -453,7 +455,7 @@ def total(self) -> Price | None: ) ) - def submitted(self, request: 'CoreRequest') -> bool: + def submitted(self, request: CoreRequest) -> bool: """ Returns true if the given request is a successful post request. """ return request.POST and self.validate() or False @@ -491,8 +493,8 @@ def title_fields(self) -> list[str]: def match_fields( self, - include_classes: 'Iterable[type[Field]] | None' = None, - exclude_classes: 'Iterable[type[Field]] | None' = None, + include_classes: Iterable[type[Field]] | None = None, + exclude_classes: Iterable[type[Field]] | None = None, required: bool | None = None, limit: int | None = None ) -> list[str]: @@ -556,7 +558,7 @@ def is_required(self, field_id: str) -> bool: def get_useful_data( self, - exclude: 'Collection[str] | None' = None + exclude: Collection[str] | None = None ) -> dict[str, Any]: """ Returns the form data in a dictionary, by default excluding data that should not be stored in the db backend. @@ -572,8 +574,8 @@ def get_useful_data( def populate_obj( self, obj: object, - exclude: 'Collection[str] | None' = None, - include: 'Collection[str] | None' = None + exclude: Collection[str] | None = None, + include: Collection[str] | None = None ) -> None: """ A reimplementation of wtforms populate_obj function with the addage of optional include/exclude filters. @@ -593,10 +595,10 @@ def populate_obj( def process( self, - formdata: '_MultiDictLike | None' = None, + formdata: _MultiDictLike | None = None, obj: object | None = None, - data: 'Mapping[str, Any] | None' = None, - extra_filters: 'Mapping[str, Sequence[Any]] | None' = None, + data: Mapping[str, Any] | None = None, + extra_filters: Mapping[str, Sequence[Any]] | None = None, **kwargs: Any ) -> None: """ Calls :meth:`process_obj` if ``process()`` was called with @@ -628,7 +630,7 @@ def process_obj(self, obj: object) -> None: def delete_field(self, fieldname: str) -> None: """ Removes the given field from the form and all the fieldsets. """ - def fieldsets_without_field() -> 'Iterator[Fieldset]': + def fieldsets_without_field() -> Iterator[Fieldset]: for fieldset in self.fieldsets: if fieldname in fieldset.fields: del fieldset.fields[fieldname] @@ -642,7 +644,7 @@ def fieldsets_without_field() -> 'Iterator[Fieldset]': def validate( self, - extra_validators: 'Mapping[str, Sequence[Any]] | None' = None + extra_validators: Mapping[str, Sequence[Any]] | None = None ) -> bool: """ Adds support for 'ensurances' to the form. An ensurance is a method which is called during validation when all the fields have @@ -670,7 +672,7 @@ def validate( return result @property - def ensurances(self) -> 'Iterator[Callable[[], bool]]': + def ensurances(self) -> Iterator[Callable[[], bool]]: """ Returns the ensurances that need to be checked when validating. This property may be overridden if only a subset of all ensurances @@ -702,7 +704,7 @@ def as_maybe_markdown(raw_text: str) -> tuple[str, bool]: def additional_field_help( self, - field: 'Field', + field: Field, length_limit: int = 54 ) -> str | None: """ Returns the field description in modified form if @@ -727,9 +729,9 @@ def additional_field_help( class Fieldset: """ Defines a fieldset with a list of fields. """ - fields: dict[str, 'CallableProxyType[Field]'] + fields: dict[str, CallableProxyType[Field]] - def __init__(self, label: str | None, fields: 'Iterable[Field]'): + def __init__(self, label: str | None, fields: Iterable[Field]): """ Initializes the Fieldset. :label: Label of the fieldset (None if it's an invisible fieldset) @@ -744,7 +746,7 @@ def __init__(self, label: str | None, fields: 'Iterable[Field]'): def __len__(self) -> int: return len(self.fields) - def __getitem__(self, key: str) -> 'CallableProxyType[Field]': + def __getitem__(self, key: str) -> CallableProxyType[Field]: return self.fields[key] @property @@ -752,7 +754,7 @@ def is_visible(self) -> bool: return self.label is not None @property - def non_empty_fields(self) -> dict[str, 'CallableProxyType[Field]']: + def non_empty_fields(self) -> dict[str, CallableProxyType[Field]]: """ Returns only the fields which are not empty. """ return OrderedDict( (id, field) for id, field in self.fields.items() if field.data) @@ -774,7 +776,7 @@ class FieldDependency: """ - dependencies: list['DependencyDict'] + dependencies: list[DependencyDict] def __init__(self, *kwargs: object): assert len(kwargs) and not len(kwargs) % 2 @@ -804,7 +806,7 @@ def __init__(self, *kwargs: object): 'choice': choice, }) - def fulfilled(self, form: Form, field: 'Field') -> bool: + def fulfilled(self, form: Form, field: Field) -> bool: result = True for dependency in self.dependencies: data = getattr(form, dependency['field_id']).data @@ -817,7 +819,7 @@ def fulfilled(self, form: Form, field: 'Field') -> bool: result = result and ((data == choice) ^ invert) return result - def unfulfilled(self, form: Form, field: 'Field') -> bool: + def unfulfilled(self, form: Form, field: Field) -> bool: return not self.fulfilled(form, field) @property @@ -839,7 +841,7 @@ class Pricing: """ - def __init__(self, rules: 'PricingRules'): + def __init__(self, rules: PricingRules): self.rules = { rule: Price( amount, @@ -855,7 +857,7 @@ def has_payment_rule(self) -> bool: price.credit_card_payment for price in self.rules.values() ) - def price(self, field: 'Field') -> Price | None: + def price(self, field: Field) -> Price | None: values = field.data if not isinstance(field.data, list): values = [values] @@ -939,7 +941,7 @@ class MergedForm(form, *forms): # type:ignore def enforce_order( form_class: type[_FormT], - fields_in_order: 'Iterable[str]' + fields_in_order: Iterable[str] ) -> type[_FormT]: """ Takes a list of fields used in a form_class and enforces the order of those fields. @@ -970,7 +972,7 @@ class EnforcedOrderForm(form_class): # type:ignore def move_fields( form_class: type[_FormT], - fields: 'Collection[str]', + fields: Collection[str], after: str | None ) -> type[_FormT]: """ Reorders the given fields (given by name) by inserting them directly diff --git a/src/onegov/form/display.py b/src/onegov/form/display.py index cc13048282..ed5fdfa9b0 100644 --- a/src/onegov/form/display.py +++ b/src/onegov/form/display.py @@ -1,4 +1,5 @@ """ Contains renderers to display form fields. """ +from __future__ import annotations import humanize import re @@ -25,12 +26,12 @@ class Registry: making sure each renderer is only instantiated once. """ - renderer_map: dict[str, 'BaseRenderer'] + renderer_map: dict[str, BaseRenderer] def __init__(self) -> None: self.renderer_map = {} - def register_for(self, *types: str) -> 'Callable[[type[_R]], type[_R]]': + def register_for(self, *types: str) -> Callable[[type[_R]], type[_R]]: """ Decorator to register a renderer. """ def wrapper(renderer: type[_R]) -> type[_R]: instance = renderer() @@ -41,7 +42,7 @@ def wrapper(renderer: type[_R]) -> type[_R]: return renderer return wrapper - def render(self, field: 'Field') -> Markup: + def render(self, field: Field) -> Markup: """ Renders the given field with the correct renderer. """ if not field.data: return Markup('') @@ -72,7 +73,7 @@ def __call__(self, field: Field) -> Markup: ... def escape(self, text: str) -> Markup: return escape(text) - def translate(self, field: 'Field', text: str) -> str: + def translate(self, field: Field, text: str) -> str: if isinstance(text, TranslationString): return field.gettext(text) @@ -84,7 +85,7 @@ def translate(self, field: 'Field', text: str) -> str: 'TextAreaField', ) class StringFieldRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: if field.render_kw: if field.render_kw.get('data-editor') == 'markdown': return render_untrusted_markdown(field.data) @@ -94,13 +95,13 @@ def __call__(self, field: 'Field') -> Markup: @registry.register_for('PasswordField') class PasswordFieldRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: return Markup('*' * len(field.data)) # noqa: RUF035 @registry.register_for('EmailField') class EmailFieldRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: params = {'href': f'mailto:{field.data}'} return Markup( # noqa: RUF035 f'{{email}}' @@ -109,7 +110,7 @@ def __call__(self, field: 'Field') -> Markup: @registry.register_for('URLField') class URLFieldRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: params = {'href': field.data} return Markup( # noqa: RUF035 f'{{url}}' @@ -134,7 +135,7 @@ class VideoURLFieldRenderer(BaseRenderer): """) url_template = Markup('{url}') - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: url = None data = field.data @@ -188,7 +189,7 @@ class DateFieldRenderer(BaseRenderer): # be doable with little work (not necessary for now) date_format = '%d.%m.%Y' - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: return self.escape(field.data.strftime(self.date_format)) @@ -204,7 +205,7 @@ class TimezoneDateTimeFieldRenderer(DateFieldRenderer): @registry.register_for('TimeField') class TimeFieldRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: return Markup( # noqa: RUF035 f'{field.data.hour:02d}:{field.data.minute:02d}' ) @@ -213,7 +214,7 @@ def __call__(self, field: 'Field') -> Markup: @registry.register_for('UploadField') class UploadFieldRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: return Markup('{filename} ({size})').format( filename=field.data['filename'], size=humanize.naturalsize(field.data['size']) @@ -223,7 +224,7 @@ def __call__(self, field: 'Field') -> Markup: @registry.register_for('UploadMultipleField') class UploadMultipleFieldRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: return Markup('
').join( Markup(' {filename} ({' 'size})').format( @@ -236,7 +237,7 @@ def __call__(self, field: 'Field') -> Markup: @registry.register_for('RadioField') class RadioFieldRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: choices = dict(field.choices) # type:ignore[attr-defined] return self.escape('✓ ' + self.translate( field, choices.get(field.data, '?') @@ -246,7 +247,7 @@ def __call__(self, field: 'Field') -> Markup: @registry.register_for('MultiCheckboxField') class MultiCheckboxFieldRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: choices = {value: f'? ({value})' for value in field.data} choices.update(field.choices) # type:ignore[attr-defined] return Markup('
').join( @@ -257,17 +258,17 @@ def __call__(self, field: 'Field') -> Markup: @registry.register_for('CSRFTokenField', 'HiddenField') class NullRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: return Markup('') @registry.register_for('DecimalField') class DecimalRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: return Markup(f'{field.data:.2f}') # noqa: RUF035 @registry.register_for('IntegerField') class IntegerRenderer(BaseRenderer): - def __call__(self, field: 'Field') -> Markup: + def __call__(self, field: Field) -> Markup: return Markup(f'{int(field.data)}') # noqa: RUF035 diff --git a/src/onegov/form/errors.py b/src/onegov/form/errors.py index adea519b5c..244374a4ea 100644 --- a/src/onegov/form/errors.py +++ b/src/onegov/form/errors.py @@ -1,3 +1,6 @@ +from __future__ import annotations + + class FormError(Exception): pass diff --git a/src/onegov/form/extensions.py b/src/onegov/form/extensions.py index 84660513e0..9c7cc4f15b 100644 --- a/src/onegov/form/extensions.py +++ b/src/onegov/form/extensions.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any, Generic, TypeVar, TYPE_CHECKING if TYPE_CHECKING: from collections.abc import Collection @@ -6,7 +8,7 @@ _FormT = TypeVar('_FormT', bound='Form') -form_extensions: dict[str, type['FormExtension[Any]']] = {} +form_extensions: dict[str, type[FormExtension[Any]]] = {} class FormExtension(Generic[_FormT]): @@ -72,7 +74,7 @@ class Extendable: def extend_form_class( self, form_class: type[_FormT], - extensions: 'Collection[str]' + extensions: Collection[str] ) -> type[_FormT]: if not extensions: return form_class diff --git a/src/onegov/form/fields.py b/src/onegov/form/fields.py index 2555e4594c..e16e502dfc 100644 --- a/src/onegov/form/fields.py +++ b/src/onegov/form/fields.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import inspect import phonenumbers import sedate @@ -90,7 +92,7 @@ class TimeField(DefaultTimeField): e.g. with the arrow keys on the form. """ - def process_formdata(self, valuelist: list['RawFormValue']) -> None: + def process_formdata(self, valuelist: list[RawFormValue]) -> None: if not valuelist: return @@ -103,7 +105,7 @@ class TranslatedSelectField(SelectField): def iter_choices( self - ) -> 'Iterator[tuple[Any, str, bool, dict[str, Any]]]': + ) -> Iterator[tuple[Any, str, bool, dict[str, Any]]]: for choice in super().iter_choices(): result = list(choice) result[1] = self.meta.request.translate(result[1]) @@ -135,18 +137,18 @@ class UploadField(FileField): def __init__( self, label: str | None = None, - validators: 'Validators[FormT, Self] | None' = None, - filters: 'Sequence[Filter]' = (), + validators: Validators[FormT, Self] | None = None, + filters: Sequence[Filter] = (), description: str = '', id: str | None = None, - default: 'Sequence[StrictFileDict]' = (), - widget: 'Widget[Self] | None' = None, + default: Sequence[StrictFileDict] = (), + widget: Widget[Self] | None = None, render_kw: dict[str, Any] | None = None, name: str | None = None, - _form: 'BaseForm | None' = None, + _form: BaseForm | None = None, _prefix: str = '', - _translations: '_SupportsGettextAndNgettext | None' = None, - _meta: 'DefaultMeta | None' = None, + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, # onegov specific kwargs that get popped off *, fieldset: str | None = None, @@ -159,7 +161,7 @@ def __init__( # unfortunately a union of two TypedDict will narrow to the TypedDict # with the fewest shared keys, which would always be an empty dictionary @property - def data(self) -> 'StrictFileDict | FileDict | None': + def data(self) -> StrictFileDict | FileDict | None: frame = inspect.currentframe() assert frame is not None and frame.f_back is not None caller = frame.f_back.f_locals.get('self') @@ -177,7 +179,7 @@ def data(self) -> 'StrictFileDict | FileDict | None': return getattr(self, '_data', None) @data.setter - def data(self, value: 'FileDict') -> None: + def data(self, value: FileDict) -> None: self._data = value @property @@ -186,7 +188,7 @@ def is_image(self) -> bool: return False return self.data.get('mimetype') in IMAGE_MIME_TYPES_AND_SVG - def process_formdata(self, valuelist: list['RawFormValue']) -> None: + def process_formdata(self, valuelist: list[RawFormValue]) -> None: if not valuelist: self.data = {} @@ -223,8 +225,8 @@ def process_formdata(self, valuelist: list['RawFormValue']) -> None: def process_fieldstorage( self, - fs: 'RawFormValue' - ) -> 'StrictFileDict | FileDict': + fs: RawFormValue + ) -> StrictFileDict | FileDict: self.file = getattr(fs, 'file', getattr(fs, 'stream', None)) self.filename = path_to_filename(getattr(fs, 'filename', None)) @@ -243,13 +245,13 @@ def process_fieldstorage( class UploadFileWithORMSupport(UploadField): """ Extends the upload field with onegov.file support. """ - file_class: type['File'] + file_class: type[File] def __init__(self, *args: Any, **kwargs: Any): self.file_class = kwargs.pop('file_class') super().__init__(*args, **kwargs) - def create(self) -> 'File | None': + def create(self) -> File | None: if not getattr(self, 'file', None): return None @@ -278,7 +280,7 @@ def populate_obj(self, obj: object, name: str) -> None: else: raise NotImplementedError(f'Unknown action: {self.action}') - def process_data(self, value: 'File | None') -> None: + def process_data(self, value: File | None) -> None: if value: try: size = value.reference.file.content_length @@ -306,7 +308,7 @@ class UploadMultipleField(UploadMultipleBase, FileField): """ widget = UploadMultipleWidget() - raw_data: list['RawFormValue'] + raw_data: list[RawFormValue] if TYPE_CHECKING: _separator: str @@ -315,29 +317,29 @@ def _add_entry(self, d: _MultiDictLikeWithGetlist, /) -> UploadField: ... upload_field_class: type[UploadField] = UploadField - upload_widget: 'Widget[UploadField]' = UploadWidget() + upload_widget: Widget[UploadField] = UploadWidget() def __init__( self, label: str | None = None, - validators: 'Validators[FormT, UploadField] | None' = None, - filters: 'Sequence[Filter]' = (), + validators: Validators[FormT, UploadField] | None = None, + filters: Sequence[Filter] = (), description: str = '', id: str | None = None, - default: 'Sequence[FileDict]' = (), - widget: 'Widget[Self] | None' = None, + default: Sequence[FileDict] = (), + widget: Widget[Self] | None = None, render_kw: dict[str, Any] | None = None, name: str | None = None, - upload_widget: 'Widget[UploadField] | None' = None, - _form: 'BaseForm | None' = None, + upload_widget: Widget[UploadField] | None = None, + _form: BaseForm | None = None, _prefix: str = '', - _translations: '_SupportsGettextAndNgettext | None' = None, - _meta: 'DefaultMeta | None' = None, + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, # onegov specific kwargs that get popped off *, fieldset: str | None = None, - depends_on: 'Sequence[Any] | None' = None, - pricing: 'PricingRules | None' = None, + depends_on: Sequence[Any] | None = None, + pricing: PricingRules | None = None, # if we change the upload_field_class there may be additional # parameters that are allowed so we pass them through **extra_arguments: Any @@ -378,9 +380,9 @@ def __bool__(self) -> Literal[True]: def process( self, - formdata: '_MultiDictLikeWithGetlist | None', + formdata: _MultiDictLikeWithGetlist | None, data: object = unset_value, - extra_filters: 'Sequence[Filter] | None' = None + extra_filters: Sequence[Filter] | None = None ) -> None: self.process_errors = [] @@ -401,7 +403,7 @@ def process( def append_entry_from_field_storage( self, - fs: '_FieldStorageWithFile' + fs: _FieldStorageWithFile ) -> UploadField: # we fake the formdata for the new field # we use a werkzeug MultiDict because the WebOb version @@ -411,7 +413,7 @@ def append_entry_from_field_storage( formdata.add(name, fs) return self._add_entry(formdata) - def process_formdata(self, valuelist: list['RawFormValue']) -> None: + def process_formdata(self, valuelist: list[RawFormValue]) -> None: if not valuelist: return @@ -425,14 +427,14 @@ def process_formdata(self, valuelist: list['RawFormValue']) -> None: class _DummyFile: - file: 'File | None' + file: File | None class UploadMultipleFilesWithORMSupport(UploadMultipleField): """ Extends the upload multiple field with onegov.file support. """ - file_class: type['File'] - added_files: list['File'] + file_class: type[File] + added_files: list[File] upload_field_class = UploadFileWithORMSupport def __init__(self, *args: Any, **kwargs: Any): @@ -494,7 +496,7 @@ def __init__(self, *args: Any, **kwargs: Any): super().__init__(*args, **kwargs) - def pre_validate(self, form: 'BaseForm') -> None: + def pre_validate(self, form: BaseForm) -> None: self.data = sanitize_html(self.data) @@ -503,7 +505,7 @@ class CssField(TextAreaField): def post_validate( self, - form: 'BaseForm', + form: BaseForm, validation_stopped: bool ) -> None: if self.data: @@ -522,7 +524,7 @@ class MarkupField(TextAreaField): data: Markup | None - def process_formdata(self, valuelist: list['RawFormValue']) -> None: + def process_formdata(self, valuelist: list[RawFormValue]) -> None: if valuelist: assert isinstance(valuelist[0], str) self.data = Markup(valuelist[0]) # noqa: RUF035 @@ -548,7 +550,7 @@ class TagsField(StringField): # passed in by the form or the object?! This seems like a bug data: str | list[str] # type:ignore[assignment] - def process_formdata(self, valuelist: list['RawFormValue']) -> None: + def process_formdata(self, valuelist: list[RawFormValue]) -> None: if not valuelist: self.data = [] return @@ -614,7 +616,7 @@ class ChosenSelectMultipleEmailField(SelectMultipleField): widget = ChosenSelectWidget(multiple=True) - def pre_validate(self, form: 'BaseForm') -> None: + def pre_validate(self, form: BaseForm) -> None: super().pre_validate(form) if not self.data: return @@ -627,9 +629,9 @@ def pre_validate(self, form: 'BaseForm') -> None: class PreviewField(Field): - fields: 'Sequence[str]' - events: 'Sequence[str]' - url: 'Callable[[DefaultMeta], str | None] | str | None' + fields: Sequence[str] + events: Sequence[str] + url: Callable[[DefaultMeta], str | None] | str | None display: str widget = PreviewWidget() @@ -637,9 +639,9 @@ class PreviewField(Field): def __init__( self, *args: Any, - fields: 'Sequence[str]' = (), - url: 'Callable[[DefaultMeta], str | None] | str | None' = None, - events: 'Sequence[str]' = (), + fields: Sequence[str] = (), + url: Callable[[DefaultMeta], str | None] | str | None = None, + events: Sequence[str] = (), display: str = 'inline', **kwargs: Any ): @@ -690,7 +692,7 @@ class DateTimeLocalField(DateTimeLocalFieldBase): def __init__( self, label: str | None = None, - validators: 'Validators[FormT, Self] | None' = None, + validators: Validators[FormT, Self] | None = None, format: str = '%Y-%m-%dT%H:%M', **kwargs: Any ): @@ -701,7 +703,7 @@ def __init__( **kwargs ) - def process_formdata(self, valuelist: list['RawFormValue']) -> None: + def process_formdata(self, valuelist: list[RawFormValue]) -> None: if valuelist: date_str = 'T'.join(valuelist).replace(' ', 'T') # type:ignore valuelist = [date_str[:16]] @@ -716,20 +718,20 @@ class TimezoneDateTimeField(DateTimeLocalField): """ - data: 'datetime | None' + data: datetime | None def __init__(self, *args: Any, timezone: str, **kwargs: Any): self.timezone = timezone super().__init__(*args, **kwargs) - def process_data(self, value: 'datetime | None') -> None: + def process_data(self, value: datetime | None) -> None: if value: value = sedate.to_timezone(value, self.timezone) value.replace(tzinfo=None) super().process_data(value) - def process_formdata(self, valuelist: list['RawFormValue']) -> None: + def process_formdata(self, valuelist: list[RawFormValue]) -> None: super().process_formdata(valuelist) if self.data: @@ -763,7 +765,7 @@ def __init__(self, *args: Any, **kwargs: Any): def post_validate( self, - form: 'Form', # type:ignore[override] + form: Form, # type:ignore[override] validation_stopped: bool ) -> None: if self.data: @@ -795,7 +797,7 @@ def coerce(self, value: object) -> str | None: def process_data(self, value: object) -> None: self.data = self.coerce(value) - def process_formdata(self, valuelist: list['RawFormValue']) -> None: + def process_formdata(self, valuelist: list[RawFormValue]) -> None: if not valuelist: self.data = None return @@ -810,14 +812,14 @@ class TypeAheadField(StringField): """ - url: 'Callable[[DefaultMeta], str | None] | str | None' + url: Callable[[DefaultMeta], str | None] | str | None widget = TypeAheadInput() def __init__( self, *args: Any, - url: 'Callable[[DefaultMeta], str | None] | str | None' = None, + url: Callable[[DefaultMeta], str | None] | str | None = None, **kwargs: Any ): self.url = url diff --git a/src/onegov/form/filters.py b/src/onegov/form/filters.py index 59f58c19d7..9028ec5764 100644 --- a/src/onegov/form/filters.py +++ b/src/onegov/form/filters.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import yubikey_public_id diff --git a/src/onegov/form/forms/__init__.py b/src/onegov/form/forms/__init__.py index f75575fee4..490e86c8f0 100644 --- a/src/onegov/form/forms/__init__.py +++ b/src/onegov/form/forms/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form.forms.named_file import NamedFileForm diff --git a/src/onegov/form/forms/named_file.py b/src/onegov/form/forms/named_file.py index a33147d95b..71a13d1307 100644 --- a/src/onegov/form/forms/named_file.py +++ b/src/onegov/form/forms/named_file.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.form.fields import UploadField from onegov.form import Form @@ -49,7 +51,7 @@ def file_fields(self) -> dict[str, UploadField]: def get_useful_data( self, - exclude: 'Collection[str] | None' = None + exclude: Collection[str] | None = None ) -> dict[str, Any]: exclude = set(exclude or ()) @@ -67,8 +69,8 @@ def get_useful_data( def populate_obj( self, obj: object, - exclude: 'Collection[str] | None' = None, - include: 'Collection[str] | None' = None + exclude: Collection[str] | None = None, + include: Collection[str] | None = None ) -> None: exclude = set(exclude or ()) diff --git a/src/onegov/form/i18n.py b/src/onegov/form/i18n.py index d0ffe24c8a..7c7fdd5098 100644 --- a/src/onegov/form/i18n.py +++ b/src/onegov/form/i18n.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.i18n.translation_string import TranslationStringFactory _ = TranslationStringFactory('onegov.form') diff --git a/src/onegov/form/integration.py b/src/onegov/form/integration.py index b5430daeff..a291a565e7 100644 --- a/src/onegov/form/integration.py +++ b/src/onegov/form/integration.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from more.webassets import WebassetsApp from onegov.core.security import Public from onegov.form import _ @@ -38,8 +40,8 @@ def get_formcode_parse_fields() -> FormcodeParseFields: @FormApp.json(model=Snippets, permission=Public) def view_formcode_snippets( self: Snippets, - request: 'CoreRequest' -) -> 'JSON_ro': + request: CoreRequest +) -> JSON_ro: return { 'labels': { 'required': request.translate(_('Required')), @@ -58,8 +60,8 @@ def view_formcode_snippets( request_method='POST') def view_parse_formcode( self: FormcodeParseFields, - request: 'CoreRequest' -) -> 'JSON_ro': + request: CoreRequest +) -> JSON_ro: formcode = request.params.get('formcode') or request.text if not formcode: @@ -89,7 +91,7 @@ def get_css_path() -> str: @FormApp.webasset('formcode') -def get_formcode_asset() -> 'Iterator[str]': +def get_formcode_asset() -> Iterator[str]: yield 'utils.js' yield 'watcher.jsx' yield 'togglebutton.jsx' @@ -99,25 +101,25 @@ def get_formcode_asset() -> 'Iterator[str]': @FormApp.webasset('iconwidget') -def get_iconwidget_asset() -> 'Iterator[str]': +def get_iconwidget_asset() -> Iterator[str]: yield 'iconwidget.css' yield 'iconwidget.js' @FormApp.webasset('preview-widget-handler') -def get_preview_widget_asset() -> 'Iterator[str]': +def get_preview_widget_asset() -> Iterator[str]: yield 'preview-widget.css' yield 'preview-widget.js' @FormApp.webasset('text-module-picker') -def get_text_module_picker_asset() -> 'Iterator[str]': +def get_text_module_picker_asset() -> Iterator[str]: yield 'text-module-picker.css' yield 'text-module-picker.js' @FormApp.webasset('lazy-wolves') -def get_honeypot_asset() -> 'Iterator[str]': +def get_honeypot_asset() -> Iterator[str]: yield 'honeypot.css' @@ -125,7 +127,7 @@ def get_honeypot_asset() -> 'Iterator[str]': 'chosen', filters={'css': ['datauri', 'custom-rcssmin']} ) -def get_chosen_asset() -> 'Iterator[str]': +def get_chosen_asset() -> Iterator[str]: # Make sure your app includes jQuery! yield 'chosen.css' yield 'chosen.fixes.css' @@ -134,7 +136,7 @@ def get_chosen_asset() -> 'Iterator[str]': @FormApp.webasset('typeahead-standalone') -def get_typeahead_asset() -> 'Iterator[str]': +def get_typeahead_asset() -> Iterator[str]: yield 'typeahead-standalone.css' yield 'typeahead-standalone.js' yield 'typeahead-standalone-init.js' diff --git a/src/onegov/form/models/__init__.py b/src/onegov/form/models/__init__.py index fc7edde1a4..4d242b50b3 100644 --- a/src/onegov/form/models/__init__.py +++ b/src/onegov/form/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form.models.definition import FormDefinition from onegov.form.models.submission import FormSubmission from onegov.form.models.definition import SurveyDefinition diff --git a/src/onegov/form/models/definition.py b/src/onegov/form/models/definition.py index 96970ac55b..91a903d07c 100644 --- a/src/onegov/form/models/definition.py +++ b/src/onegov/form/models/definition.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from wtforms import RadioField from onegov.core.orm import Base, observes from onegov.core.orm.mixins import ( @@ -44,44 +46,44 @@ def id(self) -> str: return self.name #: the name of the form (key, part of the url) - name: 'Column[str]' = Column(Text, nullable=False, primary_key=True) + name: Column[str] = Column(Text, nullable=False, primary_key=True) #: the title of the form - title: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) #: the form as parsable string - definition: 'Column[str]' = Column(Text, nullable=False) + definition: Column[str] = Column(Text, nullable=False) #: hint on how to get to the resource pick_up: dict_property[str | None] = content_property() #: the group to which this resource belongs to (may be any kind of string) - group: 'Column[str | None]' = Column(Text, nullable=True) + group: Column[str | None] = Column(Text, nullable=True) #: The normalized title for sorting - order: 'Column[str]' = Column(Text, nullable=False, index=True) + order: Column[str] = Column(Text, nullable=False, index=True) #: the checksum of the definition, forms and submissions with matching #: checksums are guaranteed to have the exact same definition - checksum: 'Column[str]' = Column(Text, nullable=False) + checksum: Column[str] = Column(Text, nullable=False) #: the type of the form, this can be used to create custom polymorphic #: subclasses. See ``_. - type: 'Column[str]' = Column( + type: Column[str] = Column( Text, nullable=False, default=lambda: 'generic' ) #: link between forms and submissions - submissions: 'relationship[list[FormSubmission]]' = relationship( + submissions: relationship[list[FormSubmission]] = relationship( FormSubmission, back_populates='form' ) #: link between forms and registration windows - registration_windows: 'relationship[list[FormRegistrationWindow]]' + registration_windows: relationship[list[FormRegistrationWindow]] registration_windows = relationship( FormRegistrationWindow, back_populates='form', @@ -102,7 +104,7 @@ def id(self) -> str: #: #: this could of course be done more conventionally, but this is cooler 😅 #: - current_registration_window: 'relationship[FormRegistrationWindow | None]' + current_registration_window: relationship[FormRegistrationWindow | None] current_registration_window = relationship( 'FormRegistrationWindow', viewonly=True, uselist=False, primaryjoin="""and_( @@ -139,7 +141,7 @@ def id(self) -> str: #: payment options ('manual' for out of band payments without cc, 'free' #: for both manual and cc payments, 'cc' for forced cc payments) - payment_method: 'Column[PaymentMethod]' = Column( + payment_method: Column[PaymentMethod] = Column( Text, # type:ignore[arg-type] nullable=False, default='manual' @@ -155,7 +157,7 @@ def id(self) -> str: } @property - def form_class(self) -> 'type_t[Form]': + def form_class(self) -> type_t[Form]: """ Parses the form definition and returns a form class. """ return self.extend_form_class( @@ -173,7 +175,7 @@ def title_observer(self, title: str) -> None: def has_submissions( self, - with_state: 'SubmissionState | None' = None + with_state: SubmissionState | None = None ) -> bool: session = object_session(self) @@ -187,8 +189,8 @@ def has_submissions( def add_registration_window( self, - start: 'date', - end: 'date', + start: date, + end: date, *, enabled: bool = True, timezone: str = 'Europe/Zurich', @@ -207,7 +209,7 @@ def add_registration_window( self.registration_windows.append(window) return window - def for_new_name(self, name: str) -> 'Self': + def for_new_name(self, name: str) -> Self: return self.__class__( name=name, title=self.title, @@ -236,32 +238,32 @@ def id(self) -> str: return self.name #: the name of the form (key, part of the url) - name: 'Column[str]' = Column(Text, nullable=False, primary_key=True) + name: Column[str] = Column(Text, nullable=False, primary_key=True) #: the title of the form - title: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) #: the form as parsable string - definition: 'Column[str]' = Column(Text, nullable=False) + definition: Column[str] = Column(Text, nullable=False) #: the group to which this resource belongs to (may be any kind of string) - group: 'Column[str | None]' = Column(Text, nullable=True) + group: Column[str | None] = Column(Text, nullable=True) #: The normalized title for sorting - order: 'Column[str]' = Column(Text, nullable=False, index=True) + order: Column[str] = Column(Text, nullable=False, index=True) #: the checksum of the definition, forms and submissions with matching #: checksums are guaranteed to have the exact same definition - checksum: 'Column[str]' = Column(Text, nullable=False) + checksum: Column[str] = Column(Text, nullable=False) #: link between surveys and submissions - submissions: 'relationship[list[SurveySubmission]]' = relationship( + submissions: relationship[list[SurveySubmission]] = relationship( SurveySubmission, back_populates='survey' ) #: link between surveys and submission windows - submission_windows: 'relationship[list[SurveySubmissionWindow]]' + submission_windows: relationship[list[SurveySubmissionWindow]] submission_windows = relationship( SurveySubmissionWindow, back_populates='survey', @@ -269,7 +271,7 @@ def id(self) -> str: cascade='all, delete-orphan' ) - current_submission_window: 'relationship[SurveySubmissionWindow | None]' + current_submission_window: relationship[SurveySubmissionWindow | None] current_submission_window = relationship( 'SurveySubmissionWindow', viewonly=True, uselist=False, primaryjoin="""and_( @@ -305,7 +307,7 @@ def id(self) -> str: extensions: dict_property[list[str]] = meta_property(default=list) @property - def form_class(self) -> type['Form']: + def form_class(self) -> type[Form]: """ Parses the survey definition and returns a form class. """ return self.extend_form_class( @@ -333,8 +335,8 @@ def has_submissions( def add_submission_window( self, - start: 'date', - end: 'date', + start: date, + end: date, *, enabled: bool = True, timezone: str = 'Europe/Zurich', @@ -349,7 +351,7 @@ def add_submission_window( self.submission_windows.append(window) return window - def get_results(self, request: 'CoreRequest', sw_id: ('UUID | None') = None + def get_results(self, request: CoreRequest, sw_id: (UUID | None) = None ) -> dict[str, Any]: """ Returns the results of the survey. """ diff --git a/src/onegov/form/models/registration_window.py b/src/onegov/form/models/registration_window.py index e5a21f07ee..96e14736cf 100644 --- a/src/onegov/form/models/registration_window.py +++ b/src/onegov/form/models/registration_window.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate from onegov.core.orm import Base @@ -45,49 +47,49 @@ class FormRegistrationWindow(Base, TimestampMixin): __tablename__ = 'registration_windows' #: the public id of the registraiton window - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the name of the form to which this registration window belongs - name: 'Column[str]' = Column( + name: Column[str] = Column( Text, ForeignKey('forms.name'), nullable=False ) #: the form to which this registration window belongs - form: 'relationship[FormDefinition]' = relationship( + form: relationship[FormDefinition] = relationship( 'FormDefinition', back_populates='registration_windows' ) #: true if the registration window is enabled - enabled: 'Column[bool]' = Column(Boolean, nullable=False, default=True) + enabled: Column[bool] = Column(Boolean, nullable=False, default=True) #: the start date of the window - start: 'Column[date]' = Column(Date, nullable=False) + start: Column[date] = Column(Date, nullable=False) #: the end date of the window - end: 'Column[date]' = Column(Date, nullable=False) + end: Column[date] = Column(Date, nullable=False) #: the timezone of the window - timezone: 'Column[str]' = Column( + timezone: Column[str] = Column( Text, nullable=False, default='Europe/Zurich' ) #: the number of spots (None => unlimited) - limit: 'Column[int | None]' = Column(Integer, nullable=True) + limit: Column[int | None] = Column(Integer, nullable=True) #: enable an overflow of submissions - overflow: 'Column[bool]' = Column(Boolean, nullable=False, default=True) + overflow: Column[bool] = Column(Boolean, nullable=False, default=True) #: submissions linked to this registration window - submissions: 'relationship[list[FormSubmission]]' = relationship( + submissions: relationship[list[FormSubmission]] = relationship( FormSubmission, back_populates='registration_window' ) @@ -117,7 +119,7 @@ class FormRegistrationWindow(Base, TimestampMixin): ) @property - def localized_start(self) -> 'datetime': + def localized_start(self) -> datetime: return sedate.align_date_to_day( sedate.standardize_date( sedate.as_datetime(self.start), self.timezone @@ -125,7 +127,7 @@ def localized_start(self) -> 'datetime': ) @property - def localized_end(self) -> 'datetime': + def localized_end(self) -> datetime: return sedate.align_date_to_day( sedate.standardize_date( sedate.as_datetime(self.end), self.timezone diff --git a/src/onegov/form/models/submission.py b/src/onegov/form/models/submission.py index a7a874a191..975d0303cd 100644 --- a/src/onegov/form/models/submission.py +++ b/src/onegov/form/models/submission.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import html from onegov.core.orm import Base, observes @@ -46,80 +48,80 @@ class FormSubmission(Base, TimestampMixin, Payable, AssociatedFiles, __tablename__ = 'submissions' #: id of the form submission - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: name of the form this submission belongs to - name: 'Column[str | None]' = Column( + name: Column[str | None] = Column( Text, ForeignKey('forms.name'), nullable=True ) #: the form this submission belongs to - form: 'relationship[FormDefinition | None]' = relationship( + form: relationship[FormDefinition | None] = relationship( 'FormDefinition', back_populates='submissions' ) #: the title of the submission, generated from the submitted fields #: NULL for submissions which are not complete - title: 'Column[str | None]' = Column(Text, nullable=True) + title: Column[str | None] = Column(Text, nullable=True) #: the e-mail address associated with the submitee, generated from the # submitted fields (may be NULL, even for complete submissions) - email: 'Column[str | None]' = Column(Text, nullable=True) + email: Column[str | None] = Column(Text, nullable=True) #: the source code of the form at the moment of submission. This is stored #: alongside the submission as the original form may change later. We #: want to keep the old form around just in case. - definition: 'Column[str]' = Column(Text, nullable=False) + definition: Column[str] = Column(Text, nullable=False) #: the exact time this submissions was changed from 'pending' to 'complete' - received: 'Column[datetime | None]' = Column(UTCDateTime, nullable=True) + received: Column[datetime | None] = Column(UTCDateTime, nullable=True) #: the checksum of the definition, forms and submissions with matching #: checksums are guaranteed to have the exact same definition - checksum: 'Column[str]' = Column(Text, nullable=False) + checksum: Column[str] = Column(Text, nullable=False) #: metadata about this submission - meta: 'Column[dict[str, Any]]' = Column(JSON, nullable=False) + meta: Column[dict[str, Any]] = Column(JSON, nullable=False) #: the submission data - data: 'Column[dict[str, Any]]' = Column(JSON, nullable=False) + data: Column[dict[str, Any]] = Column(JSON, nullable=False) #: the state of the submission - state: 'Column[SubmissionState]' = Column( + state: Column[SubmissionState] = Column( Enum('pending', 'complete', name='submission_state'), # type:ignore nullable=False ) #: the number of spots this submission wants to claim #: (only relevant if there's a registration window) - spots: 'Column[int]' = Column(Integer, nullable=False, default=0) + spots: Column[int] = Column(Integer, nullable=False, default=0) #: the number of spots this submission has actually received #: None => the decision if spots should be given is still open #: 0 => the decision was negative, no spots were given #: 1-x => the decision was positive, at least some spots were given - claimed: 'Column[int | None]' = Column( + claimed: Column[int | None] = Column( Integer, nullable=True, default=None ) #: the id of the registration window linked with this submission - registration_window_id: 'Column[uuid.UUID | None]' = Column( + registration_window_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey('registration_windows.id'), nullable=True ) #: the registration window linked with this submission - registration_window: 'relationship[FormRegistrationWindow | None]' + registration_window: relationship[FormRegistrationWindow | None] registration_window = relationship( 'FormRegistrationWindow', back_populates='submissions' @@ -128,7 +130,7 @@ class FormSubmission(Base, TimestampMixin, Payable, AssociatedFiles, #: payment options -> copied from the definition at the moment of #: submission. This is stored alongside the submission as the original #: form setting may change later. - payment_method: 'Column[PaymentMethod]' = Column( + payment_method: Column[PaymentMethod] = Column( Text, # type:ignore[arg-type] nullable=False, default='manual' @@ -146,7 +148,7 @@ class FormSubmission(Base, TimestampMixin, Payable, AssociatedFiles, ) @property - def form_class(self) -> type['Form']: + def form_class(self) -> type[Form]: """ Parses the form definition and returns a form class. """ return self.extend_form_class( @@ -155,11 +157,11 @@ def form_class(self) -> type['Form']: ) @property - def form_obj(self) -> 'Form': + def form_obj(self) -> Form: """ Returns a form instance containing the submission data. """ return self.form_class(data=self.data) - def get_email_field_data(self, form: 'Form | None' = None) -> str | None: + def get_email_field_data(self, form: Form | None = None) -> str | None: form = form or self.form_obj email_fields = form.match_fields( @@ -182,7 +184,7 @@ def definition_observer(self, definition: str) -> None: self.checksum = hash_definition(definition) @observes('state') - def state_observer(self, state: 'SubmissionState') -> None: + def state_observer(self, state: SubmissionState) -> None: if self.state == 'complete': form = self.form_class(data=self.data) @@ -195,7 +197,7 @@ def state_observer(self, state: 'SubmissionState') -> None: if not self.received: self.received = utcnow() - def update_title(self, form: 'Form') -> None: + def update_title(self, form: Form) -> None: title_fields = form.title_fields if title_fields: # NOTE: Since the title won't be rendered as Markup, it is @@ -219,7 +221,7 @@ def update_title(self, form: 'Form') -> None: registration_state: Column[RegistrationState | None] else: @hybrid_property - def registration_state(self) -> 'RegistrationState | None': + def registration_state(self) -> RegistrationState | None: if not self.spots: return None if self.claimed is None: @@ -252,10 +254,10 @@ def payable_reference(self) -> str: def process_payment( self, - price: 'Price | None', - provider: 'PaymentProvider[Any] | None' = None, + price: Price | None, + provider: PaymentProvider[Any] | None = None, token: str | None = None - ) -> 'Payment | PaymentError | bool | None': + ) -> Payment | PaymentError | bool | None: """ Takes a request, optionally with the provider and the token by the provider that can be used to charge the credit card and creates a payment record if necessary. @@ -323,21 +325,21 @@ class SurveySubmission(Base, TimestampMixin, AssociatedFiles, __tablename__ = 'survey_submissions' #: id of the form submission - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: name of the survey this submission belongs to - name: 'Column[str | None]' = Column( + name: Column[str | None] = Column( Text, ForeignKey('surveys.name'), nullable=True ) #: the survey this submission belongs to - survey: 'relationship[SurveyDefinition | None]' = relationship( + survey: relationship[SurveyDefinition | None] = relationship( 'SurveyDefinition', back_populates='submissions' ) @@ -345,27 +347,27 @@ class SurveySubmission(Base, TimestampMixin, AssociatedFiles, #: the source code of the form at the moment of submission. This is stored #: alongside the submission as the original form may change later. We #: want to keep the old form around just in case. - definition: 'Column[str]' = Column(Text, nullable=False) + definition: Column[str] = Column(Text, nullable=False) #: the checksum of the definition, forms and submissions with matching #: checksums are guaranteed to have the exact same definition - checksum: 'Column[str]' = Column(Text, nullable=False) + checksum: Column[str] = Column(Text, nullable=False) #: metadata about this submission - meta: 'Column[dict[str, Any]]' = Column(JSON, nullable=False) + meta: Column[dict[str, Any]] = Column(JSON, nullable=False) #: the submission data - data: 'Column[dict[str, Any]]' = Column(JSON, nullable=False) + data: Column[dict[str, Any]] = Column(JSON, nullable=False) #: the id of the submission window linked with this submission - submission_window_id: 'Column[uuid.UUID | None]' = Column( + submission_window_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey('submission_windows.id'), nullable=True ) #: the submission window linked with this submission - submission_window: 'relationship[SurveySubmissionWindow | None]' + submission_window: relationship[SurveySubmissionWindow | None] submission_window = relationship( 'SurveySubmissionWindow', back_populates='submissions' @@ -375,7 +377,7 @@ class SurveySubmission(Base, TimestampMixin, AssociatedFiles, extensions: dict_property[list[str]] = meta_property(default=list) @property - def form_class(self) -> type['Form']: + def form_class(self) -> type[Form]: """ Parses the form definition and returns a form class. """ return self.extend_form_class( @@ -384,7 +386,7 @@ def form_class(self) -> type['Form']: ) @property - def form_obj(self) -> 'Form': + def form_obj(self) -> Form: """ Returns a form instance containing the submission data. """ return self.form_class(data=self.data) @@ -392,7 +394,7 @@ def form_obj(self) -> 'Form': def definition_observer(self, definition: str) -> None: self.checksum = hash_definition(definition) - def update_title(self, survey: 'Form') -> None: + def update_title(self, survey: Form) -> None: title_fields = survey.title_fields if title_fields: # FIXME: Reconsider using unescape when consistently using Markup. diff --git a/src/onegov/form/models/survey_window.py b/src/onegov/form/models/survey_window.py index af74d0371c..0271361beb 100644 --- a/src/onegov/form/models/survey_window.py +++ b/src/onegov/form/models/survey_window.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate from onegov.core.orm import Base @@ -40,14 +42,14 @@ class SurveySubmissionWindow(Base, TimestampMixin): __tablename__ = 'submission_windows' #: the public id of the submission window - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the name of the survey to which this submission window belongs - name: 'Column[str]' = Column( + name: Column[str] = Column( Text, ForeignKey('surveys.name'), nullable=False @@ -57,29 +59,29 @@ class SurveySubmissionWindow(Base, TimestampMixin): title = Column(Text) #: the survey to which this submission window belongs - survey: 'relationship[SurveyDefinition]' = relationship( + survey: relationship[SurveyDefinition] = relationship( 'SurveyDefinition', back_populates='submission_windows' ) #: true if the submission window is enabled - enabled: 'Column[bool]' = Column(Boolean, nullable=False, default=True) + enabled: Column[bool] = Column(Boolean, nullable=False, default=True) #: the start date of the window - start: 'Column[date]' = Column(Date, nullable=False) + start: Column[date] = Column(Date, nullable=False) #: the end date of the window - end: 'Column[date]' = Column(Date, nullable=False) + end: Column[date] = Column(Date, nullable=False) #: the timezone of the window - timezone: 'Column[str]' = Column( + timezone: Column[str] = Column( Text, nullable=False, default='Europe/Zurich' ) #: submissions linked to this - submissions: 'relationship[list[SurveySubmission]]' = relationship( + submissions: relationship[list[SurveySubmission]] = relationship( SurveySubmission, back_populates='submission_window' ) @@ -93,7 +95,7 @@ class SurveySubmissionWindow(Base, TimestampMixin): ) @property - def localized_start(self) -> 'datetime': + def localized_start(self) -> datetime: return sedate.align_date_to_day( sedate.standardize_date( sedate.as_datetime(self.start), self.timezone @@ -101,7 +103,7 @@ def localized_start(self) -> 'datetime': ) @property - def localized_end(self) -> 'datetime': + def localized_end(self) -> datetime: return sedate.align_date_to_day( sedate.standardize_date( sedate.as_datetime(self.end), self.timezone diff --git a/src/onegov/form/parser/__init__.py b/src/onegov/form/parser/__init__.py index 354084b88e..3ef8f3851e 100644 --- a/src/onegov/form/parser/__init__.py +++ b/src/onegov/form/parser/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form.parser.core import parse_formcode from onegov.form.parser.core import flatten_fieldsets from onegov.form.parser.core import find_field diff --git a/src/onegov/form/parser/core.py b/src/onegov/form/parser/core.py index a13873f056..deeb4acb08 100644 --- a/src/onegov/form/parser/core.py +++ b/src/onegov/form/parser/core.py @@ -231,9 +231,9 @@ Integer fields optionally can have a price attached to them which will be multiplied by the supplied integer:: - Number of stamps to include = 0..30 (0.85 CHF) + Number of stamps to include = 0..30 (1.00 CHF) -This will result in a price of 0.85 CHF per stamp. +This will result in a price of 1.00 CHF per stamp. Code ~~~~ @@ -383,6 +383,7 @@ this without a price increase too: (0 CHF!) """ +from __future__ import annotations import pyparsing as pp import re @@ -515,8 +516,8 @@ def __init__(self, tag: str): def __call__( self, - fn: 'Callable[[CustomLoader, ScalarNode], pp.ParseResults]' - ) -> 'Callable[[CustomLoader, ScalarNode], pp.ParseResults]': + fn: Callable[[CustomLoader, ScalarNode], pp.ParseResults] + ) -> Callable[[CustomLoader, ScalarNode], pp.ParseResults]: CustomLoader.add_constructor(self.tag, fn) return fn @@ -524,7 +525,7 @@ def __call__( @constructor('!text') def construct_textfield( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.textfield.parse_string(node.value) @@ -532,7 +533,7 @@ def construct_textfield( @constructor('!textarea') def construct_textarea( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.textarea.parse_string(node.value) @@ -540,7 +541,7 @@ def construct_textarea( @constructor('!code') def construct_syntax( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.code.parse_string(node.value) @@ -548,7 +549,7 @@ def construct_syntax( @constructor('!email') def construct_email( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.email.parse_string(node.value) @@ -556,7 +557,7 @@ def construct_email( @constructor('!url') def construct_url( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.url.parse_string(node.value) @@ -564,7 +565,7 @@ def construct_url( @constructor('!video_url') def construct_video_url( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.video_url.parse_string(node.value) @@ -572,7 +573,7 @@ def construct_video_url( @constructor('!stdnum') def construct_stdnum( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.stdnum.parse_string(node.value) @@ -580,7 +581,7 @@ def construct_stdnum( @constructor('!date') def construct_date( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.date.parse_string(node.value) @@ -588,7 +589,7 @@ def construct_date( @constructor('!datetime') def construct_datetime( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.datetime.parse_string(node.value) @@ -596,7 +597,7 @@ def construct_datetime( @constructor('!time') def construct_time( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.time.parse_string(node.value) @@ -604,7 +605,7 @@ def construct_time( @constructor('!radio') def construct_radio( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.radio.parse_string(node.value) @@ -612,7 +613,7 @@ def construct_radio( @constructor('!checkbox') def construct_checkbox( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.checkbox.parse_string(node.value) @@ -620,7 +621,7 @@ def construct_checkbox( @constructor('!fileinput') def construct_fileinput( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.fileinput.parse_string(node.value) @@ -628,7 +629,7 @@ def construct_fileinput( @constructor('!multiplefileinput') def construct_multiplefileinput( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.multiplefileinput.parse_string(node.value) @@ -636,7 +637,7 @@ def construct_multiplefileinput( @constructor('!password') def construct_password( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.password.parse_string(node.value) @@ -644,7 +645,7 @@ def construct_password( @constructor('!decimal_range') def construct_decimal_range( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.decimal_range.parse_string(node.value) @@ -652,21 +653,21 @@ def construct_decimal_range( @constructor('!integer_range') def construct_integer_range( loader: CustomLoader, - node: 'ScalarNode' + node: ScalarNode ) -> pp.ParseResults: return ELEMENTS.integer_range.parse_string(node.value) def flatten_fieldsets( - fieldsets: 'Iterable[Fieldset]' -) -> 'Iterator[ParsedField]': + fieldsets: Iterable[Fieldset] +) -> Iterator[ParsedField]: for fieldset in fieldsets: yield from flatten_fields(fieldset.fields) def flatten_fields( - fields: 'Sequence[ParsedField] | None' -) -> 'Iterator[ParsedField]': + fields: Sequence[ParsedField] | None +) -> Iterator[ParsedField]: for field in fields or []: yield field @@ -680,9 +681,9 @@ def flatten_fields( def find_field( - fieldsets: 'Iterable[Fieldset]', + fieldsets: Iterable[Fieldset], id: str | None -) -> 'Fieldset | ParsedField | None': +) -> Fieldset | ParsedField | None: id = as_internal_id(id or '') @@ -703,7 +704,7 @@ class Fieldset: def __init__( self, label: str, - fields: 'Sequence[ParsedField] | None' = None + fields: Sequence[ParsedField] | None = None ): self.label = label if label != '...' else None self.fields = fields or [] @@ -719,7 +720,7 @@ def human_id(self) -> str: def find_field( self, id: str | None = None - ) -> 'Fieldset | ParsedField | None': + ) -> Fieldset | ParsedField | None: return find_field((self,), id=id) @@ -735,7 +736,7 @@ def __init__( key: str, label: str, selected: bool = False, - fields: 'Sequence[ParsedField] | None' = None + fields: Sequence[ParsedField] | None = None ): self.key = key self.label = label @@ -750,7 +751,7 @@ def __init__( self, label: str, required: bool, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None, human_id: str | None = None, @@ -786,7 +787,7 @@ def create( # type:ignore[misc] cls: type[_FieldT], field: pp.ParseResults, identifier: pp.ParseResults, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None ) -> _FieldT: @@ -838,10 +839,10 @@ def create( cls, field: pp.ParseResults, identifier: pp.ParseResults, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None - ) -> 'DateField': + ) -> DateField: return cls( label=identifier.label, @@ -868,10 +869,10 @@ def create( cls, field: pp.ParseResults, identifier: pp.ParseResults, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None - ) -> 'DatetimeField': + ) -> DatetimeField: return cls( label=identifier.label, @@ -900,17 +901,17 @@ def parse(self, value: Any) -> object: class StringField(Field): type: ClassVar[Literal['text']] = 'text' maxlength: int | None - regex: 'Pattern[str] | None' + regex: Pattern[str] | None @classmethod def create( cls, field: pp.ParseResults, identifier: pp.ParseResults, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None - ) -> 'StringField': + ) -> StringField: regex = field.regex and re.compile(field.regex) or None return cls( @@ -934,10 +935,10 @@ def create( cls, field: pp.ParseResults, identifier: pp.ParseResults, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None - ) -> 'TextAreaField': + ) -> TextAreaField: return cls( label=identifier.label, required=identifier.required, @@ -958,10 +959,10 @@ def create( cls, field: pp.ParseResults, identifier: pp.ParseResults, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None - ) -> 'CodeField': + ) -> CodeField: return cls( label=identifier.label, required=identifier.required, @@ -982,7 +983,7 @@ def create( cls, field: pp.ParseResults, identifier: pp.ParseResults, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None ) -> Self: @@ -999,7 +1000,7 @@ def create( @final class IntegerRangeField(Field): type: ClassVar[Literal['integer_range']] = 'integer_range' - pricing: 'PricingRules' + pricing: PricingRules range: range @classmethod @@ -1007,10 +1008,10 @@ def create( cls, field: pp.ParseResults, identifier: pp.ParseResults, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None - ) -> 'IntegerRangeField': + ) -> IntegerRangeField: if field.pricing: label = identifier.label + format_pricing(field.pricing) @@ -1041,17 +1042,17 @@ def parse(self, value: Any) -> object: @final class DecimalRangeField(Field): type: ClassVar[Literal['decimal_range']] = 'decimal_range' - range: 'decimal_range' + range: decimal_range @classmethod def create( cls, field: pp.ParseResults, identifier: pp.ParseResults, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None - ) -> 'DecimalRangeField': + ) -> DecimalRangeField: return cls( label=identifier.label, required=identifier.required, @@ -1074,7 +1075,7 @@ def create( # type:ignore[misc] cls: type[_FieldT], field: pp.ParseResults, identifier: pp.ParseResults, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None ) -> _FieldT: @@ -1100,14 +1101,14 @@ class MultipleFileinputField(FileinputBase, Field): class OptionsField: choices: list[Choice] - pricing: 'PricingRules' + pricing: PricingRules @classmethod def create( # type:ignore[misc] cls: type[_FieldT], field: pp.ParseResults, identifier: pp.ParseResults, - parent: 'ParsedField | None' = None, + parent: ParsedField | None = None, fieldset: Fieldset | None = None, field_help: str | None = None ) -> _FieldT: @@ -1202,11 +1203,11 @@ def parse_field_block( # FIXME: This is very loose, we could do better, but we want to # refactor form parsing anyways... field_block: dict[str, Any], - field_classes: dict[str, type['ParsedField']], + field_classes: dict[str, type[ParsedField]], used_ids: set[str], fieldset: Fieldset, - parent: 'ParsedField | None' = None -) -> 'ParsedField': + parent: ParsedField | None = None +) -> ParsedField: """ Takes the given parsed field block and yields the fields from it """ key, field = next(i for i in field_block.items()) @@ -1261,7 +1262,7 @@ def parse_field_block( return result -def format_pricing(pricing: 'RawPricing | None') -> str: +def format_pricing(pricing: RawPricing | None) -> str: if not pricing: return '' @@ -1288,7 +1289,7 @@ def try_parse(expr: pp.ParserElement, text: str) -> pp.ParseResults | None: return None -def prepare(text: str) -> 'Iterator[tuple[int, str]]': +def prepare(text: str) -> Iterator[tuple[int, str]]: """ Takes the raw form source and prepares it for the translation into yaml. @@ -1299,8 +1300,8 @@ def prepare(text: str) -> 'Iterator[tuple[int, str]]': def ensure_a_fieldset( - lines: 'Iterable[tuple[int, str]]' -) -> 'Iterator[tuple[int, str]]': + lines: Iterable[tuple[int, str]] +) -> Iterator[tuple[int, str]]: """ Makes sure that the given lines all belong to a fieldset. That means adding an empty fieldset before all lines, if none is found first. @@ -1333,7 +1334,7 @@ def validate_indent(indent: str) -> bool: def translate_to_yaml( text: str, enable_edit_checks: bool = False -) -> 'Iterator[str]': +) -> Iterator[str]: """ Takes the given form text and constructs an easier to parse yaml string. diff --git a/src/onegov/form/parser/form.py b/src/onegov/form/parser/form.py index 0e11d727e4..5198f7cec7 100644 --- a/src/onegov/form/parser/form.py +++ b/src/onegov/form/parser/form.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re from html import escape from onegov.form import errors @@ -114,8 +116,8 @@ def normalize_label_for_dependency(label: str) -> str: def handle_field( - builder: 'WTFormsClassBuilder[Any]', - field: 'ParsedField', + builder: WTFormsClassBuilder[Any], + field: ParsedField, dependency: FieldDependency | None = None ) -> None: """ Takes the given parsed field and adds it to the form. """ @@ -409,7 +411,7 @@ def set_current_fieldset(self, label: str | None) -> None: def validators_extend( self, - validators: list['Validator[Any, Any]'], + validators: list[Validator[Any, Any]], required: bool, dependency: FieldDependency | None ) -> None: @@ -423,7 +425,7 @@ def validators_extend( def validators_add_required( self, - validators: list['Validator[Any, Any]'] + validators: list[Validator[Any, Any]] ) -> None: # we use the DataRequired check instead of InputRequired, since # InputRequired only works if the data comes over the wire. We @@ -435,7 +437,7 @@ def validators_add_required( def validators_add_dependency( self, - validators: list['Validator[Any, Any]'], + validators: list[Validator[Any, Any]], dependency: FieldDependency ) -> None: # if the dependency is not fulfilled, the field may be empty @@ -451,7 +453,7 @@ def validators_add_dependency( def validators_add_optional( self, - validators: list['Validator[Any, Any]'] + validators: list[Validator[Any, Any]] ) -> None: validators.insert(0, StrictOptional()) @@ -488,19 +490,19 @@ def get_unique_field_id( def add_field( self, - field_class: type['WTField'], + field_class: type[WTField], field_id: str, label: str, required: bool, dependency: FieldDependency | None = None, - pricing: 'PricingRules | None' = None, - validators: list['Validator[Any, Any]'] | None = None, + pricing: PricingRules | None = None, + validators: list[Validator[Any, Any]] | None = None, description: str | None = None, - widget: 'Widget[Any] | None' = None, + widget: Widget[Any] | None = None, render_kw: dict[str, Any] | None = None, # for field classes that have more than just the base arguments **extra_field_kwargs: Any - ) -> 'WTField': + ) -> WTField: validators = validators or [] if hasattr(self.form_class, field_id): diff --git a/src/onegov/form/parser/grammar.py b/src/onegov/form/parser/grammar.py index 28ee5f5ad4..b7af7a811c 100644 --- a/src/onegov/form/parser/grammar.py +++ b/src/onegov/form/parser/grammar.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re from datetime import date as dateobj @@ -45,27 +47,27 @@ def text_without(characters: str) -> Word: return Word(printables, excludeChars=characters) -def matches(character: str) -> 'Callable[[ParseResults], bool]': +def matches(character: str) -> Callable[[ParseResults], bool]: """ Returns true if the given character matches the token. """ return lambda tokens: tokens and tokens[0] == character or False -def literal(value: _T) -> 'Callable[[ParseResults], _T]': +def literal(value: _T) -> Callable[[ParseResults], _T]: """" Returns the given value, ignoring the tokens alltogether. """ return lambda tokens: value -def as_int(tokens: 'ParseResults') -> int | None: +def as_int(tokens: ParseResults) -> int | None: """ Converts the token to int if possible. """ return int(tokens[0]) if tokens else None -def as_joined_string(tokens: 'ParseResults') -> str: +def as_joined_string(tokens: ParseResults) -> str: """ Joins the given tokens into a single string. """ return ''.join(tokens[0]) -def as_decimal(tokens: 'ParseResults') -> Decimal | None: +def as_decimal(tokens: ParseResults) -> Decimal | None: """ Converts the token to decimal if possible. """ if tokens and tokens[0] == '-': tokens = tokens[1:] @@ -76,27 +78,27 @@ def as_decimal(tokens: 'ParseResults') -> Decimal | None: return Decimal(prefix + '.'.join(tokens)) if tokens else None -def as_uppercase(tokens: 'ParseResults') -> str | None: +def as_uppercase(tokens: ParseResults) -> str | None: """ Converts the token to uppercase if possible. """ return ''.join(tokens).upper() if tokens else None -def as_integer_range(tokens: 'ParseResults') -> range | None: +def as_integer_range(tokens: ParseResults) -> range | None: """ Converts the token to an integer range if possible. """ return range(int(tokens[0]), int(tokens[1])) if tokens else None -def as_decimal_range(tokens: 'ParseResults') -> decimal_range | None: +def as_decimal_range(tokens: ParseResults) -> decimal_range | None: """ Converts the token to a decimal range if possible. """ return decimal_range(tokens[0], tokens[1]) if tokens else None -def as_regex(tokens: 'ParseResults') -> 'Pattern[str] | None': +def as_regex(tokens: ParseResults) -> Pattern[str] | None: """ Converts the token to a working regex if possible. """ return re.compile(tokens[0]) if tokens else None -def as_date(instring: str, loc: int, tokens: 'ParseResults') -> dateobj | None: +def as_date(instring: str, loc: int, tokens: ParseResults) -> dateobj | None: """ Converts the token to a date if possible. """ if not tokens: return None @@ -114,8 +116,8 @@ def approximate_total_days(delta: relativedelta) -> float: def is_valid_date_range( instring: str, loc: int, - tokens: 'ParseResults' -) -> 'ParseResults': + tokens: ParseResults +) -> ParseResults: """ Checks if the date range is valid """ if tokens: after, before = tokens @@ -142,20 +144,20 @@ def is_valid_date_range( raise ParseFatalException(instring, loc, 'Invalid date range') -def as_relative_delta(tokens: 'ParseResults') -> relativedelta | None: +def as_relative_delta(tokens: ParseResults) -> relativedelta | None: return relativedelta(**{ # type: ignore[arg-type] tokens[1]: int(tokens[0]) }) if tokens else None -def unwrap(tokens: 'ParseResults') -> Any | None: +def unwrap(tokens: ParseResults) -> Any | None: """ Unwraps grouped tokens. """ return tokens[0] if tokens else None -def tag(**tags: str) -> 'Callable[[ParseResults], None]': +def tag(**tags: str) -> Callable[[ParseResults], None]: """ Takes the given tags and applies them to the token. """ - def apply_tags(tokens: 'ParseResults') -> None: + def apply_tags(tokens: ParseResults) -> None: for key, value in tags.items(): tokens[key] = value return apply_tags @@ -185,7 +187,7 @@ def number_enclosed_in(characters: str) -> ParserElement: def choices_enclosed_in( characters: str, - choices: 'Sequence[str]' + choices: Sequence[str] ) -> ParserElement: """ Wraps the given choices in the given characters, making sure only valid choices are possible. @@ -442,7 +444,7 @@ def fileinput() -> ParserElement: extensions = Group(any_extension | OneOrMore(some_extension)) multiple = enclosed_in(Literal('multiple'), '()') - def extract_file_types(tokens: 'ParseResults') -> None: + def extract_file_types(tokens: ParseResults) -> None: if len(tokens) == 2 and tokens[1] == 'multiple': tokens['type'] = 'multiplefileinput' else: @@ -481,7 +483,7 @@ def decimal() -> ParserElement: def range_field( value_expression: ParserElement, - parse_action: 'Callable[[ParseResults], Any]', + parse_action: Callable[[ParseResults], Any], type: str ) -> ParserElement: """ Generic range field parser. """ diff --git a/src/onegov/form/parser/snippets.py b/src/onegov/form/parser/snippets.py index 38904ac046..fa24a54020 100644 --- a/src/onegov/form/parser/snippets.py +++ b/src/onegov/form/parser/snippets.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import _ @@ -66,7 +68,7 @@ class Snippets: def translated( self, - request: 'CoreRequest' - ) -> 'Iterator[tuple[str, str | None, TranslationString]]': + request: CoreRequest + ) -> Iterator[tuple[str, str | None, TranslationString]]: for title, snippet in self.fragments: yield request.translate(title), snippet, title diff --git a/src/onegov/form/submissions.py b/src/onegov/form/submissions.py index 1e76a3b4a6..edcbeab31a 100644 --- a/src/onegov/form/submissions.py +++ b/src/onegov/form/submissions.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from inspect import getmembers from wtforms.validators import DataRequired @@ -24,7 +26,7 @@ def prepare_for_submission( # force all upload fields to be simple, we do not support the more # complex add/keep/replace widget, which is hard to properly support # and is not super useful in submissions - def is_upload(attribute: object) -> 'TypeGuard[UnboundField[UploadField]]': + def is_upload(attribute: object) -> TypeGuard[UnboundField[UploadField]]: if not hasattr(attribute, 'field_class'): return False @@ -52,27 +54,27 @@ def is_upload(attribute: object) -> 'TypeGuard[UnboundField[UploadField]]': @overload def get_fields( - form_class: type['Form'], + form_class: type[Form], names_only: Literal[False] = False, - exclude: 'Collection[str] | None' = None -) -> 'Iterator[tuple[str, UnboundField[Any]]]': ... + exclude: Collection[str] | None = None +) -> Iterator[tuple[str, UnboundField[Any]]]: ... @overload def get_fields( - form_class: type['Form'], + form_class: type[Form], names_only: Literal[True], - exclude: 'Collection[str] | None' = None -) -> 'Iterator[str]': ... + exclude: Collection[str] | None = None +) -> Iterator[str]: ... def get_fields( - form_class: type['Form'], + form_class: type[Form], names_only: bool = False, - exclude: 'Collection[str] | None' = None -) -> 'Iterator[str | tuple[str, UnboundField[Any]]]': + exclude: Collection[str] | None = None +) -> Iterator[str | tuple[str, UnboundField[Any]]]: """ Takes an unbound form and returns the name of the fields """ - def is_field(attribute: object) -> 'TypeGuard[UnboundField[Any]]': + def is_field(attribute: object) -> TypeGuard[UnboundField[Any]]: return hasattr(attribute, 'field_class') for name, field in getmembers(form_class, predicate=is_field): diff --git a/src/onegov/form/types.py b/src/onegov/form/types.py index 411798de6c..f2d823c1ce 100644 --- a/src/onegov/form/types.py +++ b/src/onegov/form/types.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import TypeVar, TYPE_CHECKING BaseFormT = TypeVar('BaseFormT', bound='BaseForm', contravariant=True) diff --git a/src/onegov/form/upgrade.py b/src/onegov/form/upgrade.py index 61c5372d5b..0b1a898f05 100644 --- a/src/onegov/form/upgrade.py +++ b/src/onegov/form/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + from depot.io.utils import FileIntent from io import BytesIO from onegov.core.crypto import random_token @@ -22,13 +24,13 @@ @upgrade_task('Enable external form submissions') -def enable_external_form_submissions(context: 'UpgradeContext') -> None: +def enable_external_form_submissions(context: UpgradeContext) -> None: context.operations.alter_column('submissions', 'name', nullable=True) @upgrade_task('Set payment method for existing forms') -def set_payment_method_for_existing_forms(context: 'UpgradeContext') -> None: +def set_payment_method_for_existing_forms(context: UpgradeContext) -> None: forms = FormDefinitionCollection(context.session) for form in forms.query(): @@ -37,7 +39,7 @@ def set_payment_method_for_existing_forms(context: 'UpgradeContext') -> None: @upgrade_task('Migrate form submission files to onegov.file') def migrate_form_submission_files_to_onegov_file( - context: 'UpgradeContext' + context: UpgradeContext ) -> None: submission_ids = [ row[0] for row in @@ -88,7 +90,7 @@ def migrate_form_submission_files_to_onegov_file( @upgrade_task('Add payment_method to definitions and submissions') def add_payment_method_to_definitions_and_submissions( - context: 'UpgradeContext' + context: UpgradeContext ) -> None: context.add_column_with_defaults( @@ -112,7 +114,7 @@ def add_payment_method_to_definitions_and_submissions( @upgrade_task('Add meta dictionary to submissions') -def add_meta_directory_to_submissions(context: 'UpgradeContext') -> None: +def add_meta_directory_to_submissions(context: UpgradeContext) -> None: context.add_column_with_defaults( table='submissions', @@ -122,7 +124,7 @@ def add_meta_directory_to_submissions(context: 'UpgradeContext') -> None: @upgrade_task('Add group/order to form definitions') -def add_group_order_to_form_definitions(context: 'UpgradeContext') -> None: +def add_group_order_to_form_definitions(context: UpgradeContext) -> None: context.operations.add_column('forms', Column( 'group', Text, nullable=True @@ -136,7 +138,7 @@ def add_group_order_to_form_definitions(context: 'UpgradeContext') -> None: @upgrade_task('Add registration window columns') -def add_registration_window_columns(context: 'UpgradeContext') -> None: +def add_registration_window_columns(context: UpgradeContext) -> None: context.operations.add_column( 'submissions', Column('claimed', Integer, nullable=True) @@ -155,7 +157,7 @@ def add_registration_window_columns(context: 'UpgradeContext') -> None: @upgrade_task('Make form polymorphic type non-nullable') -def make_form_polymorphic_type_non_nullable(context: 'UpgradeContext') -> None: +def make_form_polymorphic_type_non_nullable(context: UpgradeContext) -> None: if context.has_table('forms'): context.operations.execute(""" UPDATE forms SET type = 'generic' WHERE type IS NULL; @@ -165,7 +167,7 @@ def make_form_polymorphic_type_non_nullable(context: 'UpgradeContext') -> None: @upgrade_task('Add title to submission windows') -def add_title_to_submission_windows(context: 'UpgradeContext') -> None: +def add_title_to_submission_windows(context: UpgradeContext) -> None: if not context.has_column('submission_windows', 'title'): context.add_column_with_defaults( 'submission_windows', @@ -180,7 +182,7 @@ def add_title_to_submission_windows(context: 'UpgradeContext') -> None: @upgrade_task('Remove no overlapping submission windows constraint') def remove_no_overlapping_submission_windows_constraint( - context: 'UpgradeContext' + context: UpgradeContext ) -> None: if not context.has_table('submission_windows'): return @@ -204,6 +206,6 @@ def remove_no_overlapping_submission_windows_constraint( @upgrade_task('Remove state column form survey submissions') -def remove_state_from_survey_submissions(context: 'UpgradeContext') -> None: +def remove_state_from_survey_submissions(context: UpgradeContext) -> None: if context.has_table('survey_submissions'): context.operations.drop_column('survey_submissions', 'state') diff --git a/src/onegov/form/utils.py b/src/onegov/form/utils.py index c43530f8ed..4736403a97 100644 --- a/src/onegov/form/utils.py +++ b/src/onegov/form/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import hashlib import re import wtforms.widgets.core @@ -28,8 +30,8 @@ def as_internal_id(label: str) -> str: def get_fields_from_class( - cls: type['Form'] -) -> list[tuple[str, 'UnboundField[Any]']]: + cls: type[Form] +) -> list[tuple[str, UnboundField[Any]]]: # often times FormMeta will have already calculated the fields # and stored them on the class, so we only need to calculate @@ -113,7 +115,7 @@ def __eq__(self, other: object) -> bool: other.start, other.stop, other.step ) - def __iter__(self) -> 'Self': + def __iter__(self) -> Self: return self def __next__(self) -> Decimal: diff --git a/src/onegov/form/validators.py b/src/onegov/form/validators.py index 0de8589524..dee29afb6a 100644 --- a/src/onegov/form/validators.py +++ b/src/onegov/form/validators.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import humanize import importlib import phonenumbers @@ -52,8 +54,8 @@ class If(Generic[BaseFormT, FieldT]): """ def __init__( self, - condition: 'FieldCondition[BaseFormT, FieldT]', - *validators: 'BaseValidator[BaseFormT, FieldT]' + condition: FieldCondition[BaseFormT, FieldT], + *validators: BaseValidator[BaseFormT, FieldT] ): assert len(validators) > 0, 'Need to supply at least one validator' self.condition = condition @@ -77,7 +79,7 @@ def __init__(self, format: str): module = '.'.join(p for p in format.split('.') if p) self.format = importlib.import_module('stdnum.' + module) - def __call__(self, form: 'Form', field: 'Field') -> None: + def __call__(self, form: Form, field: Field) -> None: # only do a check for filled out values, to check for the existance # of any value use DataRequired! if not field.data: @@ -107,7 +109,7 @@ class FileSizeLimit: def __init__(self, max_bytes: int): self.max_bytes = max_bytes - def __call__(self, form: 'Form', field: 'Field') -> None: + def __call__(self, form: Form, field: Field) -> None: if not field.data: return @@ -125,7 +127,7 @@ class WhitelistedMimeType: :class:`onegov.form.fields.UploadMultipleField` instance. """ - whitelist: 'Collection[str]' = { + whitelist: Collection[str] = { 'application/excel', 'application/vnd.ms-excel', 'application/msword', @@ -141,11 +143,11 @@ class WhitelistedMimeType: message = _('Files of this type are not supported.') - def __init__(self, whitelist: 'Collection[str] | None' = None): + def __init__(self, whitelist: Collection[str] | None = None): if whitelist is not None: self.whitelist = whitelist - def __call__(self, form: 'Form', field: 'Field') -> None: + def __call__(self, form: Form, field: Field) -> None: if not field.data: return @@ -166,7 +168,7 @@ class ExpectedExtensions(WhitelistedMimeType): ExpectedExtensions(['pdf']) # makes sure the given file is a pdf """ - def __init__(self, extensions: 'Sequence[str]'): + def __init__(self, extensions: Sequence[str]): # normalize extensions if len(extensions) == 1 and extensions[0] == '*': mimetypes = None @@ -205,7 +207,7 @@ class ValidFormDefinition: def __init__( self, require_email_field: bool = True, - reserved_fields: 'Collection[str] | None' = None, + reserved_fields: Collection[str] | None = None, require_title_fields: bool = False, validate_prices: bool = True ): @@ -214,7 +216,7 @@ def __init__( self.require_title_fields = require_title_fields self.validate_prices = validate_prices - def __call__(self, form: 'Form', field: 'Field') -> 'Form | None': + def __call__(self, form: Form, field: Field) -> Form | None: if not field.data: return None @@ -320,9 +322,9 @@ def __call__(self, form: 'Form', field: 'Field') -> 'Form | None': def _parse_form( self, - field: 'Field', + field: Field, enable_edit_checks: bool = True - ) -> 'Form': + ) -> Form: # XXX circular import from onegov.form import parse_form @@ -335,7 +337,7 @@ class ValidFilterFormDefinition(ValidFormDefinition): "filters only 'select' or 'multiple select' " "fields are allowed.") - def __call__(self, form: 'Form', field: 'Field') -> 'Form | None': + def __call__(self, form: Form, field: Field) -> Form | None: from onegov.form.fields import MultiCheckboxField parsed_form = super().__call__(form, field) @@ -372,7 +374,7 @@ def __init__(self, require_email_field: bool = False): invalid_field_type = _("Invalid field type for field '${label}'. Please " "use the plus-icon to add allowed field types.") - def __call__(self, form: 'Form', field: 'Field') -> 'Form | None': + def __call__(self, form: Form, field: Field) -> Form | None: from onegov.form.fields import UploadField parsed_form = super().__call__(form, field) @@ -409,7 +411,7 @@ class LaxDataRequired(DataRequired): """ - def __call__(self, form: 'BaseForm', field: 'Field') -> None: + def __call__(self, form: BaseForm, field: Field) -> None: if field.data is False: # guard against False, False is an instance of int, since # bool derives from int, so we need to check this first @@ -442,7 +444,7 @@ def is_missing(self, value: object) -> bool: return False - def __call__(self, form: 'BaseForm', field: 'Field') -> None: + def __call__(self, form: BaseForm, field: Field) -> None: raw = field.raw_data and field.raw_data[0] val = field.data @@ -469,7 +471,7 @@ class ValidPhoneNumber: def __init__( self, country: str = 'CH', - country_whitelist: 'Collection[str] | None' = None + country_whitelist: Collection[str] | None = None ): if country_whitelist: assert country in country_whitelist @@ -477,7 +479,7 @@ def __init__( self.country = country self.country_whitelist = country_whitelist - def __call__(self, form: 'Form', field: 'Field') -> None: + def __call__(self, form: Form, field: Field) -> None: if not field.data: return @@ -511,7 +513,7 @@ class ValidSwissSocialSecurityNumber: message = _('Not a valid swiss social security number.') - def __call__(self, form: 'Form', field: 'Field') -> None: + def __call__(self, form: Form, field: Field) -> None: if not field.data: return @@ -532,10 +534,10 @@ class UniqueColumnValue: """ - def __init__(self, table: type['Base']): + def __init__(self, table: type[Base]): self.table = table - def __call__(self, form: 'Form', field: 'Field') -> None: + def __call__(self, form: Form, field: Field) -> None: if field.name not in self.table.__table__.columns: # type:ignore raise RuntimeError('The field name must match a column!') @@ -567,7 +569,7 @@ def __init__( self.field_data = field_data self.message = message - def __call__(self, form: 'BaseForm', field: 'Field') -> None: + def __call__(self, form: BaseForm, field: Field) -> None: if self.field_name not in form: raise RuntimeError(f"No field named '{self.field_name}' in form") @@ -635,7 +637,7 @@ def max_date(self) -> date | None: return date.today() + self.max return self.max - def __call__(self, form: 'Form', field: 'Field') -> None: + def __call__(self, form: Form, field: Field) -> None: if field.data is None: return diff --git a/src/onegov/form/widgets.py b/src/onegov/form/widgets.py index e94566dd51..4a4fc063db 100644 --- a/src/onegov/form/widgets.py +++ b/src/onegov/form/widgets.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import humanize from contextlib import suppress @@ -37,7 +39,7 @@ class OrderedListWidget(ListWidget): """ - def __call__(self, field: 'Field', **kwargs: Any) -> Markup: + def __call__(self, field: Field, **kwargs: Any) -> Markup: # ListWidget expects a field internally, but it will only use # its id property and __iter__ method, so we can get away @@ -55,7 +57,7 @@ class FakeField: id = field.id - def __iter__(self) -> 'Iterator[Field]': + def __iter__(self) -> Iterator[Field]: return iter(ordered) return super().__call__(FakeField(), **kwargs) # type:ignore[arg-type] @@ -81,7 +83,7 @@ class CoordinateWidget(TextInput): """ - def __call__(self, field: 'Field', **kwargs: Any) -> Markup: + def __call__(self, field: Field, **kwargs: Any) -> Markup: kwargs['class_'] = (kwargs.get('class_', '') + ' coordinate').strip() return super().__call__(field, **kwargs) @@ -142,7 +144,7 @@ class UploadWidget(FileInput):
""") - def image_source(self, field: 'UploadField') -> str | None: + def image_source(self, field: UploadField) -> str | None: """ Returns the image source url if the field points to an image and if it can be done (it looks like it's possible, but I'm not super sure this is always possible). @@ -170,7 +172,7 @@ def image_source(self, field: 'UploadField') -> str | None: def template_data( self, - field: 'UploadField', + field: UploadField, force_simple: bool, resend_upload: bool, wrapper_css_class: str, @@ -225,7 +227,7 @@ def template_data( def __call__( self, - field: 'UploadField', # type:ignore[override] + field: UploadField, # type:ignore[override] **kwargs: Any ) -> Markup: @@ -271,14 +273,14 @@ def __init__(self) -> None: def render_input( self, - field: 'UploadMultipleField', + field: UploadMultipleField, **kwargs: Any ) -> Markup: return super().__call__(field, **kwargs) def __call__( self, - field: 'UploadMultipleField', # type:ignore[override] + field: UploadMultipleField, # type:ignore[override] **kwargs: Any ) -> Markup: @@ -346,7 +348,7 @@ class TextAreaWithTextModules(TextArea):
""") - def text_modules(self, field: 'StringField') -> list['TextModule']: + def text_modules(self, field: StringField) -> list[TextModule]: if not hasattr(field.meta, 'request'): # we depend on the field containing a reference to # the current request, which should be passed from @@ -357,7 +359,7 @@ def text_modules(self, field: 'StringField') -> list['TextModule']: collection = TextModuleCollection(request.session) return collection.query().all() - def __call__(self, field: 'StringField', **kwargs: Any) -> Markup: + def __call__(self, field: StringField, **kwargs: Any) -> Markup: input_html = super().__call__(field, **kwargs) text_modules = self.text_modules(field) if not text_modules: @@ -432,7 +434,7 @@ class IconWidget(TextInput):
""") - def __call__(self, field: 'Field', **kwargs: Any) -> Markup: + def __call__(self, field: Field, **kwargs: Any) -> Markup: iconfont = kwargs.pop('iconfont', self.iconfont) icons = kwargs.pop('icons', self.icons[iconfont]) @@ -460,7 +462,7 @@ def font_weight(icon: str) -> str: class ChosenSelectWidget(Select): - def __call__(self, field: 'SelectFieldBase', **kwargs: Any) -> Markup: + def __call__(self, field: SelectFieldBase, **kwargs: Any) -> Markup: kwargs['class_'] = '{} chosen-select'.format( kwargs.get('class_', '') ).strip() @@ -489,7 +491,7 @@ class PreviewWidget:
""") - def __call__(self, field: 'PreviewField', **kwargs: Any) -> Markup: + def __call__(self, field: PreviewField, **kwargs: Any) -> Markup: field.meta.request.include('preview-widget-handler') if callable(field.url): @@ -508,7 +510,7 @@ def __call__(self, field: 'PreviewField', **kwargs: Any) -> Markup: class PanelWidget: """ A widget that displays the field's text as panel (no input). """ - def __call__(self, field: 'PanelField', **kwargs: Any) -> Markup: + def __call__(self, field: PanelField, **kwargs: Any) -> Markup: text = escape(field.meta.request.translate(field.text)) return Markup( # noqa: RUF035 f'
' @@ -522,7 +524,7 @@ def __call__(self, field: 'PanelField', **kwargs: Any) -> Markup: class LinkPanelWidget(PanelWidget): """ A widget that displays a clickable link as panel (no input). """ - def __call__(self, field: 'PanelField', **kwargs: Any) -> Markup: + def __call__(self, field: PanelField, **kwargs: Any) -> Markup: text = escape(field.meta.request.translate(field.text)) return Markup( # noqa: RUF035 f'
' @@ -537,7 +539,7 @@ def __call__(self, field: 'PanelField', **kwargs: Any) -> Markup: class HoneyPotWidget(TextInput): """ A widget that displays the input normally not visible to the user. """ - def __call__(self, field: 'Field', **kwargs: Any) -> Markup: + def __call__(self, field: Field, **kwargs: Any) -> Markup: field.meta.request.include('lazy-wolves') kwargs['class_'] = (kwargs.get('class_', '') + ' lazy-wolves').strip() return super().__call__(field, **kwargs) @@ -571,7 +573,7 @@ class DateRangeInput(DateRangeMixin, DateInput): supported in some browsers based on a date or relativedelta. """ - def __call__(self, field: 'Field', **kwargs: Any) -> Markup: + def __call__(self, field: Field, **kwargs: Any) -> Markup: min_date = self.min_date if min_date is not None: kwargs.setdefault('min', min_date.isoformat()) @@ -588,7 +590,7 @@ class DateTimeLocalRangeInput(DateRangeMixin, DateTimeLocalInput): are supported in some browsers based on a date or relativedelta. """ - def __call__(self, field: 'Field', **kwargs: Any) -> Markup: + def __call__(self, field: Field, **kwargs: Any) -> Markup: min_date = self.min_date if min_date is not None: kwargs.setdefault('min', min_date.isoformat() + 'T00:00') @@ -605,7 +607,7 @@ class TypeAheadInput(TextInput): def __call__( self, - field: 'TypeAheadField', # type:ignore[override] + field: TypeAheadField, # type:ignore[override] **kwargs: Any ) -> Markup: field.meta.request.include('typeahead-standalone') diff --git a/src/onegov/foundation/__init__.py b/src/onegov/foundation/__init__.py index 97cebaace7..2d9e6a2cb8 100644 --- a/src/onegov/foundation/__init__.py +++ b/src/onegov/foundation/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.foundation.theme import BaseTheme, Theme __all__ = ('BaseTheme', 'Theme') diff --git a/src/onegov/foundation/theme.py b/src/onegov/foundation/theme.py index a74016ede7..1f029ac8b9 100644 --- a/src/onegov/foundation/theme.py +++ b/src/onegov/foundation/theme.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os.path import sass @@ -79,7 +81,7 @@ def pre_imports(self) -> list[str]: return [] @property - def foundation_components(self) -> 'Sequence[str]': + def foundation_components(self) -> Sequence[str]: """ All used foundation components. """ return ( 'grid', @@ -122,7 +124,7 @@ def foundation_components(self) -> 'Sequence[str]': ) @property - def imports(self) -> 'Iterator[str]': + def imports(self) -> Iterator[str]: """ All imports, including the foundation ones. Override with care. """ return chain( self.pre_imports, @@ -162,7 +164,7 @@ def foundation_path(self) -> str: """ return os.path.join(os.path.dirname(__file__), 'foundation') - def compile(self, options: 'Mapping[str, Any] | None' = None) -> str: + def compile(self, options: Mapping[str, Any] | None = None) -> str: """ Compiles the theme with the given options. """ # copy, because the dict may be static if it's a basic property diff --git a/src/onegov/foundation6/__init__.py b/src/onegov/foundation6/__init__.py index 6f46ff1454..31eae719c1 100644 --- a/src/onegov/foundation6/__init__.py +++ b/src/onegov/foundation6/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.foundation6.theme import BaseTheme, Theme __all__ = ('BaseTheme', 'Theme') diff --git a/src/onegov/foundation6/cli.py b/src/onegov/foundation6/cli.py index 73cd1a6961..f11dc13e7e 100644 --- a/src/onegov/foundation6/cli.py +++ b/src/onegov/foundation6/cli.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os import shutil import sys diff --git a/src/onegov/foundation6/integration.py b/src/onegov/foundation6/integration.py index bc734e1f2e..de693ec821 100644 --- a/src/onegov/foundation6/integration.py +++ b/src/onegov/foundation6/integration.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core import Framework from onegov.core.layout import ChameleonLayout @@ -18,7 +20,7 @@ def get_foundation_js_path() -> str: @FoundationApp.webasset('foundation6') -def get_foundation_js_assets() -> 'Iterator[str]': +def get_foundation_js_assets() -> Iterator[str]: yield 'jquery.js' yield 'what-input.js' yield 'foundation.min.js' @@ -26,6 +28,6 @@ def get_foundation_js_assets() -> 'Iterator[str]': class FoundationLayout(ChameleonLayout): - def __init__(self, model: object, request: 'CoreRequest'): + def __init__(self, model: object, request: CoreRequest): super().__init__(model, request) self.request.include('foundation6') diff --git a/src/onegov/foundation6/theme.py b/src/onegov/foundation6/theme.py index 3470c9cceb..72bfe9f083 100644 --- a/src/onegov/foundation6/theme.py +++ b/src/onegov/foundation6/theme.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os.path import textwrap @@ -109,7 +111,7 @@ def foundation_helpers(self) -> str: """) @property - def foundation_config_vars(self) -> 'Sequence[str]': + def foundation_config_vars(self) -> Sequence[str]: vars = [] vars.append( f'$flex: {"true" if self.use_flex else "false"};\n' @@ -145,7 +147,7 @@ def foundation_grid(self) -> str: """) @property - def foundation_styles(self) -> 'Sequence[str]': + def foundation_styles(self) -> Sequence[str]: """The default styles""" return 'global-styles', 'forms', 'typography' @@ -189,7 +191,7 @@ def foundation_components(self) -> tuple[str, ...]: ) @property - def foundation_motion_ui(self) -> 'Sequence[str]': + def foundation_motion_ui(self) -> Sequence[str]: if self.include_motion_ui: return 'motion-ui-transitions', 'motion-ui-animations' return [] @@ -231,7 +233,7 @@ def vendor_path(self) -> str: os.path.dirname(__file__), 'foundation', 'vendor') @property - def includes(self) -> 'Iterator[str]': + def includes(self) -> Iterator[str]: not_allowed = ('flex-classes', 'flex-grid', 'grid', 'xy-grid-classes', 'visibility-classes', 'prototype-classes', 'float-classes', 'global-styles', 'forms', 'typography') @@ -247,7 +249,7 @@ def includes(self) -> 'Iterator[str]': (f'@include {i};' for i in self.foundation_motion_ui) ) - def compile(self, options: 'Mapping[str, Any] | None' = None) -> str: + def compile(self, options: Mapping[str, Any] | None = None) -> str: """ Compiles the theme with the given options. """ # copy, because the dict may be static if it's a basic property diff --git a/src/onegov/fsi/__init__.py b/src/onegov/fsi/__init__.py index 5881ca614c..5939525936 100644 --- a/src/onegov/fsi/__init__.py +++ b/src/onegov/fsi/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.fsi') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/fsi/app.py b/src/onegov/fsi/app.py index 31a284edaa..f059000420 100644 --- a/src/onegov/fsi/app.py +++ b/src/onegov/fsi/app.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core import utils from onegov.fsi.initial_content import create_new_organisation from onegov.fsi.models.course_attendee import CourseAttendee @@ -45,7 +47,7 @@ def configure_organisation( **cfg ) - def on_login(self, request: 'CoreRequest', user: 'User') -> None: + def on_login(self, request: CoreRequest, user: User) -> None: assert hasattr(user, 'attendee') if not user.attendee: user.attendee = CourseAttendee() @@ -68,7 +70,7 @@ def get_theme() -> FsiTheme: @FsiApp.setting(section='org', name='create_new_organisation') def get_create_new_organisation_factory( -) -> 'Callable[[FsiApp, str], Organisation]': +) -> Callable[[FsiApp, str], Organisation]: return create_new_organisation @@ -89,6 +91,6 @@ def get_webasset_output() -> str: @FsiApp.webasset('common') -def get_common_asset() -> 'Iterator[str]': +def get_common_asset() -> Iterator[str]: yield from default_common_asset() yield 'fsi.js' diff --git a/src/onegov/fsi/cli.py b/src/onegov/fsi/cli.py index b75ef68124..990630f5fd 100644 --- a/src/onegov/fsi/cli.py +++ b/src/onegov/fsi/cli.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import click import json import transaction @@ -34,7 +36,7 @@ cli = command_group() -def do_ims_import(path: str, request: 'FsiRequest') -> None: +def do_ims_import(path: str, request: FsiRequest) -> None: _errors, persons, courses, events, possible_ldap_users = parse_ims_data( f'{path}/Teilnehmer.txt', f'{path}/Ausführungen.txt', @@ -53,23 +55,23 @@ def do_ims_import(path: str, request: 'FsiRequest') -> None: @cli.command(name='import-ims-data', context_settings={'singular': True}) @click.option('--path', help='Path with pre-named files', required=True) -def import_ims_data_cli(path: str) -> 'Callable[[FsiRequest, FsiApp], None]': +def import_ims_data_cli(path: str) -> Callable[[FsiRequest, FsiApp], None]: - def execute(request: 'FsiRequest', app: 'FsiApp') -> None: + def execute(request: FsiRequest, app: FsiApp) -> None: do_ims_import(path, request) return execute @cli.command(name='correct-ims-data', context_settings={'singular': True}) @click.option('--path', help='Path Ausführungen.txt', required=False) -def correct_ims_data_cli(path: str) -> 'Callable[[FsiRequest, FsiApp], None]': +def correct_ims_data_cli(path: str) -> Callable[[FsiRequest, FsiApp], None]: - def fix_original_ims_import(request: 'FsiRequest', app: 'FsiApp') -> None: + def fix_original_ims_import(request: FsiRequest, app: FsiApp) -> None: # Import of data was done according to timestamps 15.01.2020 session = request.session def delete_events_without_subscriptions( - session: 'Session' + session: Session ) -> tuple[int, int]: query = session.query(CourseEvent).filter( cast(CourseEvent.created, Date) == date(2020, 1, 15) @@ -99,9 +101,9 @@ def correct_datetime(dt: datetime) -> datetime: @with_open def open_events_file( - csvfile: 'CSVFile[DefaultRow]', - session: 'Session' - ) -> tuple[set['UUID'], list[str]]: + csvfile: CSVFile[DefaultRow], + session: Session + ) -> tuple[set[UUID], list[str]]: corrected_event_ids: set[UUID] = set() control_messages: list[str] = [] for line in csvfile.lines: @@ -186,9 +188,9 @@ def open_events_file( def import_teacher_data_cli( path: str, clear: bool -) -> 'Callable[[FsiRequest, FsiApp], None]': +) -> Callable[[FsiRequest, FsiApp], None]: - def execute(request: 'FsiRequest', app: 'FsiApp') -> None: + def execute(request: FsiRequest, app: FsiApp) -> None: import_teacher_data(path, request, clear) return execute @@ -201,7 +203,7 @@ def execute(request: 'FsiRequest', app: 'FsiApp') -> None: @click.option('--ldap-password', required=True) @click.option('--sort-by', required=True, default='mail') def test_ldap( - base: 'Sequence[str]', + base: Sequence[str], search_filter: str, ldap_server: str, ldap_username: str, @@ -272,7 +274,7 @@ def fetch_users_cli( verbose: bool, skip_deactivate: bool, dry_run: bool -) -> 'Callable[[FsiRequest, FsiApp], None]': +) -> Callable[[FsiRequest, FsiApp], None]: r""" Updates the list of users/course attendees by fetching matching users from a remote LDAP server. @@ -292,7 +294,7 @@ def fetch_users_cli( """ - def execute(request: 'FsiRequest', app: 'FsiApp') -> None: + def execute(request: FsiRequest, app: FsiApp) -> None: if dry_run and hasattr(app, 'es_orm_events'): # disable search indexing during operation @@ -316,8 +318,8 @@ def execute(request: 'FsiRequest', app: 'FsiApp') -> None: def fetch_users( - app: 'FsiApp', - session: 'Session', + app: FsiApp, + session: Session, ldap_server: str, ldap_username: str, ldap_password: str, @@ -334,7 +336,7 @@ def fetch_users( editor_group = editor_group.lower() sources = ZugUserSource.factory(verbose=verbose) - def users(connection: 'LDAPConnection') -> 'Iterator[dict[str, Any]]': + def users(connection: LDAPConnection) -> Iterator[dict[str, Any]]: for src in sources: for base, search_filter, attrs in src.bases_filters_attributes: success = connection.search( @@ -355,7 +357,7 @@ def users(connection: 'LDAPConnection') -> 'Iterator[dict[str, Any]]': search_filter=search_filter ) - def handle_inactive(synced_ids: list['UUID']) -> None: + def handle_inactive(synced_ids: list[UUID]) -> None: inactive = session.query(User).filter( and_( User.id.notin_(synced_ids), diff --git a/src/onegov/fsi/collections/attendee.py b/src/onegov/fsi/collections/attendee.py index ea440fd678..59ac56f770 100644 --- a/src/onegov/fsi/collections/attendee.py +++ b/src/onegov/fsi/collections/attendee.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sqlalchemy import or_ from onegov.core.collection import Pagination, GenericCollection @@ -19,7 +21,7 @@ class CourseAttendeeCollection( def __init__( self, - session: 'Session', + session: Session, page: int = 0, exclude_external: bool = False, external_only: bool = False, @@ -66,7 +68,7 @@ def attendee_permissions(self) -> list[str]: return self.auth_attendee.permissions or [] return [] - def query(self) -> 'Query[CourseAttendee]': + def query(self) -> Query[CourseAttendee]: query = super().query() query = query.order_by( @@ -93,14 +95,14 @@ def query(self) -> 'Query[CourseAttendee]': return query - def subset(self) -> 'Query[CourseAttendee]': + def subset(self) -> Query[CourseAttendee]: return self.query() @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__( self.session, index, exclude_external=self.exclude_external, @@ -120,7 +122,7 @@ def add_from_user(self, user: User) -> CourseAttendee: def by_id( self, - id: 'UUID' # type:ignore[override] + id: UUID # type:ignore[override] ) -> CourseAttendee | None: # FIXME: Is this super() call intentional? This means we don't actually # respect all of our filters for this method... diff --git a/src/onegov/fsi/collections/audit.py b/src/onegov/fsi/collections/audit.py index 52784f2a82..66a94495d9 100644 --- a/src/onegov/fsi/collections/audit.py +++ b/src/onegov/fsi/collections/audit.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from sedate import utcnow from sqlalchemy import func, desc @@ -67,8 +69,8 @@ class AuditCollection( def __init__( self, - session: 'Session', - course_id: 'UUID | None', + session: Session, + course_id: UUID | None, auth_attendee: CourseAttendee, organisations: list[str] | None = None, letter: str | None = None, @@ -89,14 +91,14 @@ def __init__( self.letter = letter.upper() if letter else None self.exclude_inactive = exclude_inactive - def subset(self) -> 'Query[AuditRow]': + def subset(self) -> Query[AuditRow]: return self.query() @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__( self.session, page=index, @@ -111,7 +113,7 @@ def by_letter_and_orgs( self, letter: str | None = None, orgs: list[str] | None = None - ) -> 'Self': + ) -> Self: return self.__class__( self.session, page=0, @@ -122,7 +124,7 @@ def by_letter_and_orgs( exclude_inactive=self.exclude_inactive ) - def by_letter(self, letter: str | None) -> 'Self': + def by_letter(self, letter: str | None) -> Self: return self.__class__( self.session, page=0, @@ -147,7 +149,7 @@ def __eq__(self, other: object) -> bool: def ranked_subscription_query( self, past_only: bool = True - ) -> 'Query[RankedSubscriptionRow]': + ) -> Query[RankedSubscriptionRow]: """ Ranks all subscriptions of all events of a course windowed over the attendee_id and ranked after completed, most recent @@ -180,7 +182,7 @@ def ranked_subscription_query( ranked = ranked.filter(CourseEvent.start < utcnow()) return ranked - def last_subscriptions(self) -> 'Query[LastSubscriptionRow]': + def last_subscriptions(self) -> Query[LastSubscriptionRow]: """Retrieve the last completed subscription by attemdee for a given the course_id. """ @@ -195,7 +197,7 @@ def last_subscriptions(self) -> 'Query[LastSubscriptionRow]': ).select_entity_from(ranked) return subquery.filter(ranked.c.rownum == 1) - def filter_attendees_by_role(self, query: 'Query[T]') -> 'Query[T]': + def filter_attendees_by_role(self, query: Query[T]) -> Query[T]: """Filter permissions of editor, exclude external, """ if self.auth_attendee.role == 'admin': if not self.organisations: @@ -212,7 +214,7 @@ def filter_attendees_by_role(self, query: 'Query[T]') -> 'Query[T]': ) if self.organisations else editors_permissions) ) - def query(self) -> 'Query[AuditRow]': + def query(self) -> Query[AuditRow]: last = self.last_subscriptions().subquery() query = self.session.query( CourseAttendee.id, @@ -245,8 +247,8 @@ def query(self) -> 'Query[AuditRow]': def next_subscriptions( self, - request: 'FsiRequest' - ) -> dict['UUID', tuple[str, 'datetime']]: + request: FsiRequest + ) -> dict[UUID, tuple[str, datetime]]: next_subscriptions: dict[UUID, tuple[str, datetime]] = {} if self.course_id: # FIXME: We can do this in a single query, this is N+1... @@ -285,7 +287,7 @@ def used_letters(self) -> list[str]: return [r.letter for r in query if r.letter] @cached_property - def relevant_courses(self) -> tuple[tuple['UUID', str], ...]: + def relevant_courses(self) -> tuple[tuple[UUID, str], ...]: return tuple(self.session.query(Course.id, Course.name).filter( Course.hidden_from_public == False, Course.mandatory_refresh != None diff --git a/src/onegov/fsi/collections/course.py b/src/onegov/fsi/collections/course.py index 8ed673b22e..62cac36267 100644 --- a/src/onegov/fsi/collections/course.py +++ b/src/onegov/fsi/collections/course.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.collection import GenericCollection from onegov.fsi.models.course import Course @@ -13,9 +15,9 @@ class CourseCollection(GenericCollection[Course]): def __init__( self, - session: 'Session', + session: Session, # TODO: Why do we have this argument? We don't use it - auth_attendee: 'CourseAttendee | None' = None, + auth_attendee: CourseAttendee | None = None, show_hidden_from_public: bool = False, ) -> None: super().__init__(session) @@ -26,7 +28,7 @@ def __init__( def model_class(self) -> type[Course]: return Course - def query(self) -> 'Query[Course]': + def query(self) -> Query[Course]: query = super().query() if not self.show_hidden_from_public: query = query.filter_by(hidden_from_public=False) @@ -34,11 +36,11 @@ def query(self) -> 'Query[Course]': def by_id( self, - id: 'UUID' # type:ignore[override] + id: UUID # type:ignore[override] ) -> Course | None: return super().query().filter(self.primary_key == id).first() - def toggled_hidden(self) -> 'Self': + def toggled_hidden(self) -> Self: return self.__class__( self.session, self.auth_attendee, diff --git a/src/onegov/fsi/collections/course_event.py b/src/onegov/fsi/collections/course_event.py index e3aef8bad2..85e369b0a9 100644 --- a/src/onegov/fsi/collections/course_event.py +++ b/src/onegov/fsi/collections/course_event.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import datetime from sedate import utcnow from sqlalchemy import desc @@ -26,7 +28,7 @@ class CourseEventCollection( def __init__( self, - session: 'Session', + session: Session, page: int = 0, from_date: datetime | None = None, upcoming_only: bool = False, @@ -34,7 +36,7 @@ def __init__( limit: int | None = None, show_hidden: bool = False, show_locked: bool = True, - course_id: 'UUID | None' = None, + course_id: UUID | None = None, sort_desc: bool = False ) -> None: @@ -76,7 +78,7 @@ def course(self) -> Course | None: return None return CourseCollection(self.session).by_id(self.course_id) - def query(self) -> 'Query[CourseEvent]': + def query(self) -> Query[CourseEvent]: query = super().query() if not self.show_hidden: query = query.filter(CourseEvent.hidden_from_public == False) @@ -101,14 +103,14 @@ def query(self) -> 'Query[CourseEvent]': return query - def subset(self) -> 'Query[CourseEvent]': + def subset(self) -> Query[CourseEvent]: return self.query() @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__( self.session, page=index, @@ -123,15 +125,15 @@ def page_by_index(self, index: int) -> 'Self': ) @classmethod - def latest(cls, session: 'Session', limit: int = 5) -> 'Self': + def latest(cls, session: Session, limit: int = 5) -> Self: return cls(session, upcoming_only=True, limit=limit) - def next_event(self) -> 'Query[CourseEvent]': + def next_event(self) -> Query[CourseEvent]: return self.query().filter( self.model_class.start > utcnow()).order_by(None).order_by( self.model_class.start) - def get_past_reminder_date(self) -> 'Query[CourseEvent]': + def get_past_reminder_date(self) -> Query[CourseEvent]: return super().query().filter( self.model_class.scheduled_reminder > utcnow()) @@ -153,11 +155,11 @@ class PastCourseEventCollection(CourseEventCollection): def __init__( self, - session: 'Session', + session: Session, page: int = 0, show_hidden: bool = False, show_locked: bool = True, - course_id: 'UUID | None' = None + course_id: UUID | None = None ) -> None: super().__init__( session, @@ -169,7 +171,7 @@ def __init__( sort_desc=True ) - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__( self.session, page=index, @@ -178,5 +180,5 @@ def page_by_index(self, index: int) -> 'Self': course_id=self.course_id, ) - def query(self) -> 'Query[CourseEvent]': + def query(self) -> Query[CourseEvent]: return super().query().filter(self.model_class.status == 'confirmed') diff --git a/src/onegov/fsi/collections/notification_template.py b/src/onegov/fsi/collections/notification_template.py index 9abdf9889c..4c80c6f5a8 100644 --- a/src/onegov/fsi/collections/notification_template.py +++ b/src/onegov/fsi/collections/notification_template.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.collection import GenericCollection @@ -24,8 +26,8 @@ class CourseNotificationTemplateCollection( def __init__( self, - session: 'Session', - course_event_id: 'UUID | None' = None + session: Session, + course_event_id: UUID | None = None ) -> None: super().__init__(session) self.course_event_id = course_event_id @@ -39,14 +41,14 @@ def course_event(self) -> CourseEvent | None: return self.session.query(CourseEvent).filter_by( id=self.course_event_id).first() - def query(self) -> 'Query[CourseNotificationTemplate]': + def query(self) -> Query[CourseNotificationTemplate]: query = super().query() if self.course_event_id: query = query.filter_by(course_event_id=self.course_event_id) return query @cached_property - def course_reservations(self) -> 'Query[CourseSubscription]': + def course_reservations(self) -> Query[CourseSubscription]: assert self.course_event is not None return self.course_event.subscriptions diff --git a/src/onegov/fsi/collections/subscription.py b/src/onegov/fsi/collections/subscription.py index ac95fbdad2..dd6dbb2060 100644 --- a/src/onegov/fsi/collections/subscription.py +++ b/src/onegov/fsi/collections/subscription.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sqlalchemy import or_ from onegov.core.collection import GenericCollection, Pagination @@ -23,9 +25,9 @@ class SubscriptionsCollection( def __init__( self, - session: 'Session', - attendee_id: 'UUID | None' = None, - course_event_id: 'UUID | None' = None, + session: Session, + attendee_id: UUID | None = None, + course_event_id: UUID | None = None, external_only: bool = False, auth_attendee: CourseAttendee | None = None, page: int = 0 @@ -79,7 +81,7 @@ def for_himself(self) -> bool: return False return str(self.auth_attendee.id) == str(self.attendee_id) - def query(self) -> 'Query[CourseSubscription]': + def query(self) -> Query[CourseSubscription]: query = super().query() if self.auth_attendee and self.auth_attendee.role == 'editor': query = query.join(CourseAttendee) @@ -99,18 +101,18 @@ def query(self) -> 'Query[CourseSubscription]': def by_id( self, - id: 'UUID' # type:ignore[override] + id: UUID # type:ignore[override] ) -> CourseSubscription | None: return super().query().filter(self.primary_key == id).first() - def subset(self) -> 'Query[CourseSubscription]': + def subset(self) -> Query[CourseSubscription]: return self.query() @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__( self.session, page=index, auth_attendee=self.auth_attendee, diff --git a/src/onegov/fsi/cronjobs.py b/src/onegov/fsi/cronjobs.py index 911bbee893..a711e53aa3 100644 --- a/src/onegov/fsi/cronjobs.py +++ b/src/onegov/fsi/cronjobs.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sedate import utcnow from onegov.core.templates import render_template @@ -11,7 +13,7 @@ from onegov.fsi.request import FsiRequest -def send_scheduled_reminders(request: 'FsiRequest') -> None: +def send_scheduled_reminders(request: FsiRequest) -> None: events = CourseEventCollection( request.session, @@ -46,5 +48,5 @@ def send_scheduled_reminders(request: 'FsiRequest') -> None: @FsiApp.cronjob(hour=8, minute=30, timezone='Europe/Zurich') -def send_reminder_mails(request: 'FsiRequest') -> None: +def send_reminder_mails(request: FsiRequest) -> None: send_scheduled_reminders(request) diff --git a/src/onegov/fsi/custom.py b/src/onegov/fsi/custom.py index 9254d5c69a..b62bf59b86 100644 --- a/src/onegov/fsi/custom.py +++ b/src/onegov/fsi/custom.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.elements import Link from onegov.core.utils import Bunch from onegov.form.collection import SurveyCollection @@ -22,7 +24,7 @@ from onegov.town6.layout import NavigationEntry -def get_base_tools(request: 'FsiRequest') -> 'Iterator[Link | LinkGroup]': +def get_base_tools(request: FsiRequest) -> Iterator[Link | LinkGroup]: if request.is_logged_in: @@ -154,12 +156,12 @@ def get_base_tools(request: 'FsiRequest') -> 'Iterator[Link | LinkGroup]': ), attrs={'class': 'register'}) -def get_global_tools(request: 'FsiRequest') -> 'Iterator[Link | LinkGroup]': +def get_global_tools(request: FsiRequest) -> Iterator[Link | LinkGroup]: yield from get_base_tools(request) @FsiApp.template_variables() -def get_template_variables(request: 'FsiRequest') -> dict[str, Any]: +def get_template_variables(request: FsiRequest) -> dict[str, Any]: return { 'global_tools': tuple(get_global_tools(request)), 'top_navigation': tuple(get_top_navigation(request)), @@ -167,7 +169,7 @@ def get_template_variables(request: 'FsiRequest') -> dict[str, Any]: } -def get_top_navigation(request: 'FsiRequest') -> 'Iterator[NavigationEntry]': +def get_top_navigation(request: FsiRequest) -> Iterator[NavigationEntry]: yield ( # type:ignore[misc] Bunch(id=-3, access='public', published=True), diff --git a/src/onegov/fsi/forms/audit.py b/src/onegov/fsi/forms/audit.py index 1133222885..5b97d7ea5b 100644 --- a/src/onegov/fsi/forms/audit.py +++ b/src/onegov/fsi/forms/audit.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.form import Form from onegov.form.fields import ChosenSelectMultipleField @@ -17,8 +19,8 @@ class AuditForm(Form): - model: 'AuditCollection' - request: 'FsiRequest' + model: AuditCollection + request: FsiRequest course_id = SelectField( label=_('Course'), @@ -52,7 +54,7 @@ def distinct_organisations(self) -> tuple[str, ...]: return tuple(a.organisation for a in query) @cached_property - def courses(self) -> tuple[tuple['UUID', str], ...]: + def courses(self) -> tuple[tuple[UUID, str], ...]: return self.model.relevant_courses @cached_property @@ -64,7 +66,7 @@ def att(self) -> CourseAttendee: # NOTE: We assume that every user is a CourseAttendee return self.request.attendee # type:ignore[return-value] - def get_course_choices(self) -> list['_Choice']: + def get_course_choices(self) -> list[_Choice]: if not self.courses: return [self.none_choice] return [(str(course_id), name) for course_id, name in self.courses] diff --git a/src/onegov/fsi/forms/course.py b/src/onegov/fsi/forms/course.py index f53ad968e0..e0de6266bc 100644 --- a/src/onegov/fsi/forms/course.py +++ b/src/onegov/fsi/forms/course.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re from collections import OrderedDict @@ -149,7 +151,7 @@ class CourseForm(Form): def get_useful_data( self, - exclude: 'Collection[str] | None' = None + exclude: Collection[str] | None = None ) -> dict[str, Any]: result = super().get_useful_data(exclude) @@ -167,7 +169,7 @@ def ensure_refresh_interval(self) -> bool: return False return True - def apply_model(self, model: 'Course') -> None: + def apply_model(self, model: Course) -> None: self.name.data = model.name self.description.data = model.description self.mandatory_refresh.data = model.mandatory_refresh @@ -175,7 +177,7 @@ def apply_model(self, model: 'Course') -> None: self.hidden_from_public.data = model.hidden_from_public self.evaluation_url.data = model.evaluation_url - def update_model(self, model: 'Course') -> None: + def update_model(self, model: Course) -> None: assert self.name.data is not None model.name = self.name.data model.description = linkify(self.description.data) @@ -199,7 +201,7 @@ class InviteCourseForm(Form): # This should be its own method really... def get_useful_data( # type:ignore[override] self, - exclude: 'Collection[str] | None' = None + exclude: Collection[str] | None = None ) -> tuple[str, ...]: string = self.attendees.data or '' return tuple(t[0] for t in _email_regex.findall(string)) diff --git a/src/onegov/fsi/forms/course_attendee.py b/src/onegov/fsi/forms/course_attendee.py index 6a3afd0da6..7f20cbaa54 100644 --- a/src/onegov/fsi/forms/course_attendee.py +++ b/src/onegov/fsi/forms/course_attendee.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.form import Form from onegov.form.fields import ChosenSelectMultipleField, ChosenSelectField @@ -17,7 +19,7 @@ class CourseAttendeeForm(Form): - request: 'FsiRequest' + request: FsiRequest first_name = StringField( label=_('First Name'), diff --git a/src/onegov/fsi/forms/course_event.py b/src/onegov/fsi/forms/course_event.py index 1e9d2d885e..eb1272037e 100644 --- a/src/onegov/fsi/forms/course_event.py +++ b/src/onegov/fsi/forms/course_event.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate from onegov.form import Form @@ -18,7 +20,7 @@ class CourseEventForm(Form): - request: 'FsiRequest' + request: FsiRequest course_id = ChosenSelectField( label=_('Course'), @@ -141,7 +143,7 @@ def on_request(self) -> None: self.status.default = 'created' @staticmethod - def fix_utc_to_local_time(db_time: 'datetime | None') -> 'datetime | None': + def fix_utc_to_local_time(db_time: datetime | None) -> datetime | None: # Todo: TimezoneDateTimeField.process_data is not called when applying # the date from the database in apply model return db_time and sedate.to_timezone( diff --git a/src/onegov/fsi/forms/notification.py b/src/onegov/fsi/forms/notification.py index dc2ed60d50..5c0a77ef8a 100644 --- a/src/onegov/fsi/forms/notification.py +++ b/src/onegov/fsi/forms/notification.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.form import Form from onegov.form.fields import MultiCheckboxField @@ -28,18 +30,18 @@ class NotificationForm(Form): render_kw={'rows': 10, 'cols': 12}, ) - def apply_model(self, model: 'CourseNotificationTemplate') -> None: + def apply_model(self, model: CourseNotificationTemplate) -> None: self.subject.data = model.subject self.text.data = model.text - def update_model(self, model: 'CourseNotificationTemplate') -> None: + def update_model(self, model: CourseNotificationTemplate) -> None: model.subject = self.subject.data model.text = self.text.data class NotificationTemplateSendForm(Form): - model: 'CourseNotificationTemplate' + model: CourseNotificationTemplate recipients = MultiCheckboxField( label=_('Recipients'), @@ -51,11 +53,11 @@ def has_recipients(self) -> bool: return len(self.attendees) > 0 @cached_property - def attendees(self) -> list['CourseAttendee']: + def attendees(self) -> list[CourseAttendee]: return [a for a in self.model.course_event.attendees if a.active] @cached_property - def recipients_choices(self) -> list['_Choice']: + def recipients_choices(self) -> list[_Choice]: return [(a.id, a.email) for a in self.attendees] def on_request(self) -> None: diff --git a/src/onegov/fsi/forms/subscription.py b/src/onegov/fsi/forms/subscription.py index 0d6c79bf57..9d1d450453 100644 --- a/src/onegov/fsi/forms/subscription.py +++ b/src/onegov/fsi/forms/subscription.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import datetime import pytz from sqlalchemy import desc @@ -22,7 +24,7 @@ class SubscriptionFormMixin: model: CourseSubscription - request: 'FsiRequest' + request: FsiRequest @property def event(self) -> CourseEvent: @@ -38,7 +40,7 @@ def event_collection(self) -> CourseEventCollection: ) @property - def attendee(self) -> 'CourseAttendee | None': + def attendee(self) -> CourseAttendee | None: return self.model.attendee def event_choice(self, event: CourseEvent) -> tuple[str, str]: @@ -46,7 +48,7 @@ def event_choice(self, event: CourseEvent) -> tuple[str, str]: def attendee_choice( self, - attendee: 'CourseAttendee | None' + attendee: CourseAttendee | None ) -> tuple[str, str]: if not attendee: return self.none_choice @@ -64,7 +66,7 @@ def none_choice(self) -> tuple[str, str]: class AddFsiSubscriptionForm(Form, SubscriptionFormMixin): - request: 'FsiRequest' + request: FsiRequest attendee_id = ChosenSelectField( label=_('Attendee'), @@ -91,7 +93,7 @@ def attendee_collection(self) -> CourseAttendeeCollection: auth_attendee=self.request.attendee ) - def get_event_choices(self) -> list['_Choice']: + def get_event_choices(self) -> list[_Choice]: if self.model.course_event_id: return [self.event_choice(self.event)] @@ -108,7 +110,7 @@ def get_event_choices(self) -> list['_Choice']: return [self.event_choice(e) for e in events] or [self.none_choice] - def get_attendee_choices(self) -> list['_Choice']: + def get_attendee_choices(self) -> list[_Choice]: if self.model.attendee_id: return [self.attendee_choice(self.attendee)] @@ -202,7 +204,7 @@ def ensure_can_book_if_locked(self) -> bool: class AddFsiPlaceholderSubscriptionForm(Form, SubscriptionFormMixin): - request: 'FsiRequest' + request: FsiRequest course_event_id = ChosenSelectField( label=_('Course Event'), @@ -216,7 +218,7 @@ class AddFsiPlaceholderSubscriptionForm(Form, SubscriptionFormMixin): label=_('Placeholder Description (optional)'), ) - def get_event_choices(self) -> list['_Choice']: + def get_event_choices(self) -> list[_Choice]: if self.model.course_event_id: return [self.event_choice(self.event)] @@ -241,7 +243,7 @@ class EditFsiSubscriptionForm(Form, SubscriptionFormMixin): The view of this form is not accessible for members """ - request: 'FsiRequest' + request: FsiRequest attendee_id = ChosenSelectField( label=_('Attendee'), @@ -273,10 +275,10 @@ def apply_model(self, model: CourseSubscription) -> None: self.course_event_id.data = model.course_event_id self.attendee_id.data = model.attendee_id - def get_event_choices(self) -> list['_Choice']: + def get_event_choices(self) -> list[_Choice]: return [self.event_choice(self.model.course_event)] - def get_attendee_choices(self) -> list['_Choice']: + def get_attendee_choices(self) -> list[_Choice]: attendees = self.model.course_event.possible_subscribers( external_only=False ) @@ -291,7 +293,7 @@ def on_request(self) -> None: class EditFsiPlaceholderSubscriptionForm(Form, SubscriptionFormMixin): - request: 'FsiRequest' + request: FsiRequest course_event_id = ChosenSelectField( label=_('Course Event'), @@ -316,7 +318,7 @@ def apply_model(self, model: CourseSubscription) -> None: self.course_event_id.data = model.course_event_id self.dummy_desc.data = model.dummy_desc - def get_event_choices(self) -> list['_Choice']: + def get_event_choices(self) -> list[_Choice]: return [self.event_choice(self.model.course_event)] def on_request(self) -> None: diff --git a/src/onegov/fsi/i18n.py b/src/onegov/fsi/i18n.py index 56b7787305..d60de4e0f7 100644 --- a/src/onegov/fsi/i18n.py +++ b/src/onegov/fsi/i18n.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.i18n.translation_string import TranslationStringFactory _ = TranslationStringFactory('onegov.fsi') diff --git a/src/onegov/fsi/ims_import.py b/src/onegov/fsi/ims_import.py index 3fe2a0960d..14242cfad2 100644 --- a/src/onegov/fsi/ims_import.py +++ b/src/onegov/fsi/ims_import.py @@ -92,6 +92,8 @@ wurden berücksichtigt, sofern eine Email vorlag. """ +from __future__ import annotations + import dateutil.parser from collections import OrderedDict, defaultdict from datetime import datetime @@ -176,15 +178,15 @@ def parse_date( val: str | None, # NOTE: Seems like PEP-696 does not allow assigning a TypeVar to its # default value yet, this should probably be allowed - default: 'DefaultT' = None # type:ignore[assignment] -) -> 'datetime | DefaultT': + default: DefaultT = None # type:ignore[assignment] +) -> datetime | DefaultT: if not val: return default date_ = dateutil.parser.parse(val) return replace_timezone(date_, 'UTC') -def parse_status(val: str) -> 'EventStatusType': +def parse_status(val: str) -> EventStatusType: mapping: dict[str, EventStatusType] = { 'Abgeschlossen': 'confirmed', 'Abgesagt': 'canceled', @@ -206,9 +208,9 @@ def validate_integer( def with_open( - func: 'Callable[[CSVFile[DefaultRow], *Ts], T]' -) -> 'Callable[[str, *Ts], T]': - def _read(filename: str, /, *args: *Ts) -> 'T': + func: Callable[[CSVFile[DefaultRow], *Ts], T] +) -> Callable[[str, *Ts], T]: + def _read(filename: str, /, *args: *Ts) -> T: with open(filename, 'rb') as f: file = CSVFile( f, @@ -221,8 +223,8 @@ def _read(filename: str, /, *args: *Ts) -> 'T': @with_open def import_teacher_data( - csvfile: CSVFile['DefaultRow'], - request: 'FsiRequest', + csvfile: CSVFile[DefaultRow], + request: FsiRequest, clean: bool = False ) -> None: @@ -288,7 +290,7 @@ def parse_completed(val: str | None) -> bool: @with_open -def parse_persons(csvfile: CSVFile['DefaultRow']) -> dict[str, 'PersonDict']: +def parse_persons(csvfile: CSVFile[DefaultRow]) -> dict[str, PersonDict]: """Pure extracting information""" persons: dict[str, PersonDict] = OrderedDict() print('-- parse_persons --') @@ -310,7 +312,7 @@ def parse_persons(csvfile: CSVFile['DefaultRow']) -> dict[str, 'PersonDict']: @with_open def parse_courses( - csvfile: CSVFile['DefaultRow'] + csvfile: CSVFile[DefaultRow] ) -> tuple[dict[int, str], dict[str, Course]]: errors = OrderedDict() courses = OrderedDict() @@ -332,7 +334,7 @@ def parse_courses( @with_open def parse_events( - csvfile: CSVFile['DefaultRow'], + csvfile: CSVFile[DefaultRow], courses: dict[str, Course] ) -> tuple[dict[int, str], dict[str, CourseEvent]]: events = OrderedDict() @@ -390,10 +392,10 @@ def parse_events( @with_open def parse_subscriptions( - csvfile: CSVFile['DefaultRow'], - persons: dict[str, 'PersonDict'], + csvfile: CSVFile[DefaultRow], + persons: dict[str, PersonDict], events: dict[str, CourseEvent] -) -> tuple[dict[int, str], dict[str, 'PersonDict'], dict[str, 'UserDict']]: +) -> tuple[dict[int, str], dict[str, PersonDict], dict[str, UserDict]]: """ :param csvfile: @@ -504,9 +506,9 @@ def parse_subscriptions( def map_persons_to_known_ldap_user( - person_record: 'PersonDict | UserDict', - session: 'Session' -) -> 'CourseAttendee | None': + person_record: PersonDict | UserDict, + session: Session +) -> CourseAttendee | None: """ Since the exported persons table contains records without email from various sources, we have to try to map it to an existing record @@ -560,10 +562,10 @@ def parse_ims_data( persons_file: str, ) -> tuple[ dict[str, dict[int, str]], - dict[str, 'PersonDict'] | None, + dict[str, PersonDict] | None, dict[str, Course] | None, dict[str, CourseEvent] | None, - dict[str, 'UserDict'] | None + dict[str, UserDict] | None ]: gathered_errors = {} @@ -591,11 +593,11 @@ def parse_ims_data( def import_ims_data( - session: 'Session', - persons: dict[str, 'PersonDict'], + session: Session, + persons: dict[str, PersonDict], courses: dict[str, Course], events: dict[str, CourseEvent], - possible_ldap_users: dict[str, 'UserDict'] + possible_ldap_users: dict[str, UserDict] ) -> dict[str, int]: print('-- Import IMS DATA to database with LDAP --') diff --git a/src/onegov/fsi/initial_content.py b/src/onegov/fsi/initial_content.py index 22de01a38f..8e99ec9a9e 100644 --- a/src/onegov/fsi/initial_content.py +++ b/src/onegov/fsi/initial_content.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import module_path from onegov.org.initial_content import load_content, add_pages from onegov.org.models import Organisation @@ -9,7 +11,7 @@ def create_new_organisation( - app: 'FsiApp', + app: FsiApp, name: str, locale: str = 'de_CH' ) -> Organisation: diff --git a/src/onegov/fsi/layout.py b/src/onegov/fsi/layout.py index 6edcd932ab..7213ca6a07 100644 --- a/src/onegov/fsi/layout.py +++ b/src/onegov/fsi/layout.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.fsi.models.course_event import ( COURSE_EVENT_STATUSES_TRANSLATIONS, COURSE_EVENT_STATUSES ) @@ -17,16 +19,16 @@ class FormatMixin: - request: 'FsiRequest' + request: FsiRequest @staticmethod - def format_status(model_status: 'EventStatusType') -> str: + def format_status(model_status: EventStatusType) -> str: return COURSE_EVENT_STATUSES_TRANSLATIONS[ COURSE_EVENT_STATUSES.index(model_status) ] @staticmethod - def format_notification_type(notification_type: 'NotificationType') -> str: + def format_notification_type(notification_type: NotificationType) -> str: return NOTIFICATION_TYPE_TRANSLATIONS[ NOTIFICATION_TYPES.index(notification_type) ] @@ -38,8 +40,8 @@ def format_boolean(self, val: bool) -> str: class DefaultLayout(BaseLayout, FormatMixin): - app: 'FsiApp' - request: 'FsiRequest' + app: FsiApp + request: FsiRequest def instance_link(self, instance: object) -> str: return self.request.link(instance) diff --git a/src/onegov/fsi/layouts/audit.py b/src/onegov/fsi/layouts/audit.py index 1d690b6781..e721b39f19 100644 --- a/src/onegov/fsi/layouts/audit.py +++ b/src/onegov/fsi/layouts/audit.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import timedelta from functools import cached_property @@ -15,7 +17,7 @@ class AuditLayout(DefaultLayout): - model: 'AuditCollection' + model: AuditCollection @property def title(self) -> str: @@ -44,8 +46,8 @@ def editbar_links(self) -> list[Link | LinkGroup]: def render_start_end( self, - start: 'datetime | None', - end: 'datetime | None' + start: datetime | None, + end: datetime | None ) -> str: if not start: return '-' @@ -67,9 +69,9 @@ def format_refresh_interval(self, num_years: int) -> str: @staticmethod def next_event_date( - start: 'datetime | None', + start: datetime | None, refresh_interval: int | None - ) -> 'datetime | None': + ) -> datetime | None: if not start: return None if refresh_interval is None: diff --git a/src/onegov/fsi/layouts/course.py b/src/onegov/fsi/layouts/course.py index 245dd88339..cbb86e55d8 100644 --- a/src/onegov/fsi/layouts/course.py +++ b/src/onegov/fsi/layouts/course.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.elements import Link, Confirm, Intercooler @@ -23,9 +25,9 @@ class CourseInviteMailLayout(OrgDefaultMailLayout, FormatMixin): """Takes a course as its model, not a notification template """ - app: 'FsiApp' - request: 'FsiRequest' - model: 'Course' + app: FsiApp + request: FsiRequest + model: Course @cached_property def event_collection(self) -> CourseEventCollection: @@ -33,7 +35,7 @@ def event_collection(self) -> CourseEventCollection: self.request.session, course_id=self.model.id, upcoming_only=True) @cached_property - def default_macros(self) -> 'MacrosLookup': + def default_macros(self) -> MacrosLookup: return self.template_loader.macros @cached_property @@ -96,7 +98,7 @@ def editbar_links(self) -> list[Link | LinkGroup]: def accordion_items( self, upcoming_only: bool = True - ) -> list['RenderData']: + ) -> list[RenderData]: assert self.request.attendee is not None coll = CourseEventCollection( @@ -119,7 +121,7 @@ def accordion_items( class CourseLayout(CourseCollectionLayout): - model: 'Course' + model: Course @cached_property def audit_collection(self) -> AuditCollection: @@ -222,7 +224,7 @@ def title(self) -> str: class EditCourseLayout(DefaultLayout): - model: 'Course' + model: Course @property def title(self) -> str: @@ -244,7 +246,7 @@ def breadcrumbs(self) -> list[Link]: class InviteCourseLayout(DefaultLayout): - model: 'Course' + model: Course @property def title(self) -> str: diff --git a/src/onegov/fsi/layouts/course_attendee.py b/src/onegov/fsi/layouts/course_attendee.py index 6dd2a1a347..8c95382661 100644 --- a/src/onegov/fsi/layouts/course_attendee.py +++ b/src/onegov/fsi/layouts/course_attendee.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.elements import Link, LinkGroup, Confirm, Intercooler @@ -90,7 +92,7 @@ def menu(self) -> list[tuple[str, str, bool]]: class CourseAttendeeLayout(DefaultLayout): - model: 'CourseAttendee' + model: CourseAttendee @cached_property def title(self) -> str: diff --git a/src/onegov/fsi/layouts/course_event.py b/src/onegov/fsi/layouts/course_event.py index 5dc34d01fe..0f876853af 100644 --- a/src/onegov/fsi/layouts/course_event.py +++ b/src/onegov/fsi/layouts/course_event.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.elements import Link, Confirm, Intercooler, LinkGroup @@ -21,7 +23,7 @@ class CourseEventCollectionLayout(DefaultLayout): model: CourseEventCollection @cached_property - def course(self) -> 'Course | None': + def course(self) -> Course | None: if self.model.course_id is None: return None @@ -73,11 +75,11 @@ def editbar_links(self) -> list[Link | LinkGroup]: return links - def subscriptions_link(self, event: 'CourseEvent') -> str: + def subscriptions_link(self, event: CourseEvent) -> str: return self.request.link(SubscriptionsCollection( self.request.session, course_event_id=event.id)) - def audit_link(self, course: 'Course | None') -> str | None: + def audit_link(self, course: Course | None) -> str | None: if not course: return None assert self.request.attendee is not None @@ -90,7 +92,7 @@ def audit_link(self, course: 'Course | None') -> str | None: class CourseEventLayout(DefaultLayout): - model: 'CourseEvent' + model: CourseEvent @property def title(self) -> str: diff --git a/src/onegov/fsi/layouts/notification.py b/src/onegov/fsi/layouts/notification.py index d766e2c1ac..d14176c822 100644 --- a/src/onegov/fsi/layouts/notification.py +++ b/src/onegov/fsi/layouts/notification.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.elements import Link, LinkGroup @@ -24,9 +26,9 @@ class MailLayout(OrgDefaultMailLayout, FormatMixin): Takes in a notification template linked to a course_event. """ - app: 'FsiApp' - request: 'FsiRequest' - model: 'CourseNotificationTemplate' + app: FsiApp + request: FsiRequest + model: CourseNotificationTemplate @property def title(self) -> str: @@ -36,7 +38,7 @@ def title(self) -> str: ) @cached_property - def default_macros(self) -> 'MacrosLookup': + def default_macros(self) -> MacrosLookup: return self.template_loader.macros @cached_property @@ -44,7 +46,7 @@ def edit_link(self) -> str: return self.request.link(self.model, name='edit') @cached_property - def base(self) -> 'PageTemplateFile': + def base(self) -> PageTemplateFile: return self.template_loader['mail_layout.pt'] @cached_property @@ -92,7 +94,7 @@ def open_events_url(self) -> str: return self.request.link(self.upcoming_events_collection) @cached_property - def events_list(self) -> list['CourseEvent']: + def events_list(self) -> list[CourseEvent]: return self.upcoming_events_collection.query().all() @cached_property @@ -142,7 +144,7 @@ def accordion_items(self) -> tuple[AccordionItem, ...]: class NotificationTemplateLayout(DefaultLayout): - model: 'CourseNotificationTemplate' + model: CourseNotificationTemplate @cached_property def title(self) -> str: diff --git a/src/onegov/fsi/layouts/subscription.py b/src/onegov/fsi/layouts/subscription.py index d257f031f0..8021200708 100644 --- a/src/onegov/fsi/layouts/subscription.py +++ b/src/onegov/fsi/layouts/subscription.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.elements import Link, Confirm, Intercooler, LinkGroup @@ -19,12 +21,12 @@ class SubscriptionCollectionLayout(DefaultLayout): def for_himself(self) -> bool: return self.model.attendee_id == self.request.attendee_id - def link(self, subscription: 'CourseSubscription') -> str: + def link(self, subscription: CourseSubscription) -> str: if subscription.is_placeholder: return self.request.link(subscription, name='edit-placeholder') return self.request.link(subscription.attendee) - def confirmation_link(self, subscription: 'CourseSubscription') -> str: + def confirmation_link(self, subscription: CourseSubscription) -> str: return self.csrf_protected_url( self.request.link(subscription, name='toggle-confirm')) @@ -103,7 +105,7 @@ def editbar_links(self) -> list[Link | LinkGroup]: return links @cached_property - def course_event(self) -> 'CourseEvent | None': + def course_event(self) -> CourseEvent | None: return self.model.course_event @cached_property @@ -144,7 +146,7 @@ def breadcrumbs(self) -> list[Link]: def intercooler_btn_for_item( self, - subscription: 'CourseSubscription' + subscription: CourseSubscription ) -> Link: confirm = subscription.is_placeholder and Confirm( @@ -177,7 +179,7 @@ def intercooler_btn_for_item( class SubscriptionLayout(DefaultLayout): """ Only used for editing since it does not contain fields """ - model: 'CourseSubscription' + model: CourseSubscription @cached_property def collection(self) -> SubscriptionsCollection: diff --git a/src/onegov/fsi/models/__init__.py b/src/onegov/fsi/models/__init__.py index 06ed35b021..d8ae29b239 100644 --- a/src/onegov/fsi/models/__init__.py +++ b/src/onegov/fsi/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.fsi.models.course import Course from onegov.fsi.models.course_attendee import CourseAttendee from onegov.fsi.models.course_event import CourseEvent diff --git a/src/onegov/fsi/models/course.py b/src/onegov/fsi/models/course.py index 6ed1f19c9f..1716a66b7a 100644 --- a/src/onegov/fsi/models/course.py +++ b/src/onegov/fsi/models/course.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.html import html_to_text from onegov.core.orm import Base from onegov.core.orm.types import MarkupText, UUID @@ -27,36 +29,36 @@ class Course(Base, ORMSearchable): } es_public = True - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) - name: 'Column[str]' = Column(Text, nullable=False, unique=True) + name: Column[str] = Column(Text, nullable=False, unique=True) - description: 'Column[Markup]' = Column(MarkupText, nullable=False) + description: Column[Markup] = Column(MarkupText, nullable=False) # saved as integer (years), accessed as years - refresh_interval: 'Column[int | None]' = Column(Integer) + refresh_interval: Column[int | None] = Column(Integer) # If the course has to be refreshed after some interval - mandatory_refresh: 'Column[bool]' = Column( + mandatory_refresh: Column[bool] = Column( Boolean, nullable=False, default=False ) # hides the course in the collection for non-admins - hidden_from_public: 'Column[bool]' = Column( + hidden_from_public: Column[bool] = Column( Boolean, nullable=False, default=False ) - evaluation_url: 'Column[str | None]' = Column(Text) + evaluation_url: Column[str | None] = Column(Text) - events: 'relationship[AppenderQuery[CourseEvent]]' = relationship( + events: relationship[AppenderQuery[CourseEvent]] = relationship( 'CourseEvent', back_populates='course', lazy='dynamic' @@ -76,7 +78,7 @@ def lead(self) -> str: return text @property - def description_html(self) -> 'Markup': + def description_html(self) -> Markup: """ Returns the description that is saved as HTML from the redactor js plugin. @@ -84,7 +86,7 @@ def description_html(self) -> 'Markup': return self.description @hybrid_property - def future_events(self) -> 'Query[CourseEvent]': + def future_events(self) -> Query[CourseEvent]: from onegov.fsi.models import CourseEvent return self.events.filter(CourseEvent.start > utcnow()).order_by( CourseEvent.start) diff --git a/src/onegov/fsi/models/course_attendee.py b/src/onegov/fsi/models/course_attendee.py index 697c96f3ff..2e3e4b003e 100644 --- a/src/onegov/fsi/models/course_attendee.py +++ b/src/onegov/fsi/models/course_attendee.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import datetime import pytz from onegov.core.orm import Base @@ -53,14 +55,14 @@ class CourseAttendee(Base, ORMSearchable): es_public = False - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) # is null if its an external attendee - user_id: 'Column[uuid.UUID | None]' = Column( + user_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey('users.id'), nullable=True @@ -68,17 +70,17 @@ class CourseAttendee(Base, ORMSearchable): # FIXME: It's not great that we insert a backref on User across # module boundaries here. This technically violates the # separation of modules. Do we need this? - user: 'relationship[User | None]' = relationship( + user: relationship[User | None] = relationship( 'User', backref=backref('attendee', uselist=False)) # mirrors user active property - active: 'Column[bool]' = Column(Boolean, nullable=False, default=True) + active: Column[bool] = Column(Boolean, nullable=False, default=True) # mirrors the source_id field from user due to performance reasons - source_id: 'Column[str | None]' = Column(Text, nullable=True) + source_id: Column[str | None] = Column(Text, nullable=True) - first_name: 'Column[str | None]' = Column(Text, nullable=True) - last_name: 'Column[str | None]' = Column(Text, nullable=True) + first_name: Column[str | None] = Column(Text, nullable=True) + last_name: Column[str | None] = Column(Text, nullable=True) # The organization this user belongs to, which may be a path like this: # @@ -98,11 +100,11 @@ class CourseAttendee(Base, ORMSearchable): # BD / HBA / Planungsbaukommission" and "BD / HBA" to access all of # "BD / HBA / *" # - organisation: 'Column[str | None]' = Column(Text, nullable=True) + organisation: Column[str | None] = Column(Text, nullable=True) - permissions: 'Column[list[str] | None]' = Column(ARRAY(Text), default=list) + permissions: Column[list[str] | None] = Column(ARRAY(Text), default=list) - _email: 'Column[str | None]' = Column(Text, unique=True) + _email: Column[str | None] = Column(Text, unique=True) def __str__(self) -> str: if self.first_name and self.last_name: @@ -115,14 +117,14 @@ def __str__(self) -> str: return mail return 'NO NAME NO EMAIL' - meta: 'Column[dict[str, Any] | None]' = Column( + meta: Column[dict[str, Any] | None] = Column( JSON, # FIXME: Why is this nullable=True if we set a default? nullable=True, default=dict ) - subscriptions: 'relationship[AppenderQuery[CourseSubscription]]' + subscriptions: relationship[AppenderQuery[CourseSubscription]] subscriptions = relationship( 'CourseSubscription', back_populates='attendee', @@ -172,7 +174,7 @@ def email(self, value: str) -> None: self._email = value @property - def course_events(self) -> 'Query[CourseEvent]': + def course_events(self) -> Query[CourseEvent]: """ Will return the query for not completed (future) courses events the attendee has a subscription record. @@ -189,19 +191,19 @@ def course_events(self) -> 'Query[CourseEvent]': return result @property - def confirmed_course_events(self) -> 'Query[CourseEvent]': + def confirmed_course_events(self) -> Query[CourseEvent]: """ Registered future course events which have been confirmed """ from onegov.fsi.models import CourseEvent return self.course_events.filter(CourseEvent.status == 'confirmed') @property - def total_done_course_events(self) -> 'Query[CourseSubscription]': + def total_done_course_events(self) -> Query[CourseSubscription]: from onegov.fsi.models import CourseSubscription # circular return self.subscriptions.filter( CourseSubscription.event_completed == True) @property - def repeating_courses(self) -> 'Query[CourseEvent]': + def repeating_courses(self) -> Query[CourseEvent]: """ Will return query to filter for all upcoming courses the attendee has to refresh. @@ -231,7 +233,7 @@ def repeating_courses(self) -> 'Query[CourseEvent]': ) @property - def undone_registered_courses(self) -> 'Query[CourseEvent]': + def undone_registered_courses(self) -> Query[CourseEvent]: from onegov.fsi.models import CourseEvent from onegov.fsi.models import CourseSubscription @@ -247,7 +249,7 @@ def possible_course_events( self, show_hidden: bool = True, show_locked: bool = False - ) -> 'Query[CourseEvent]': + ) -> Query[CourseEvent]: """Used for the subscription form. Should exclude past courses and courses already registered""" from onegov.fsi.models import CourseEvent diff --git a/src/onegov/fsi/models/course_event.py b/src/onegov/fsi/models/course_event.py index 6305c6b143..73c90f7225 100644 --- a/src/onegov/fsi/models/course_event.py +++ b/src/onegov/fsi/models/course_event.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import datetime import pytz @@ -44,7 +46,7 @@ ] -COURSE_EVENT_STATUSES: tuple['EventStatusType', ...] = ( +COURSE_EVENT_STATUSES: tuple[EventStatusType, ...] = ( 'created', 'confirmed', 'canceled', 'planned') COURSE_EVENT_STATUSES_TRANSLATIONS = ( _('Created'), _('Confirmed'), _('Canceled'), _('Planned')) @@ -52,30 +54,30 @@ @overload def course_status_choices( - request: 'FsiRequest | None' = None, + request: FsiRequest | None = None, as_dict: Literal[False] = False -) -> list['_Choice']: ... +) -> list[_Choice]: ... @overload def course_status_choices( - request: 'FsiRequest | None', + request: FsiRequest | None, as_dict: Literal[True] ) -> list[dict[str, str]]: ... @overload def course_status_choices( - request: 'FsiRequest | None' = None, + request: FsiRequest | None = None, *, as_dict: Literal[True] ) -> list[dict[str, str]]: ... def course_status_choices( - request: 'FsiRequest | None' = None, + request: FsiRequest | None = None, as_dict: bool = False -) -> list['_Choice'] | list[dict[str, str]]: +) -> list[_Choice] | list[dict[str, str]]: if request: translations: Iterable[str] = ( @@ -104,18 +106,18 @@ class CourseEvent(Base, TimestampMixin, ORMSearchable): 'presenter_email': {'type': 'text'}, } - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) - course_id: 'Column[uuid.UUID]' = Column( + course_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('fsi_courses.id'), nullable=False ) - course: 'relationship[Course]' = relationship( + course: relationship[Course] = relationship( 'Course', back_populates='events', lazy='joined' @@ -142,7 +144,7 @@ def lead(self) -> str: ) @property - def description(self) -> 'Markup': + def description(self) -> Markup: return self.course.description def __str__(self) -> str: @@ -159,26 +161,26 @@ def localized_end(self) -> datetime.datetime: return to_timezone(self.end, 'Europe/Zurich') # Event specific information - location: 'Column[str]' = Column(Text, nullable=False) - start: 'Column[datetime.datetime]' = Column(UTCDateTime, nullable=False) - end: 'Column[datetime.datetime]' = Column(UTCDateTime, nullable=False) - presenter_name: 'Column[str]' = Column(Text, nullable=False) - presenter_company: 'Column[str]' = Column(Text, nullable=False) - presenter_email: 'Column[str | None]' = Column(Text) - min_attendees: 'Column[int]' = Column( + location: Column[str] = Column(Text, nullable=False) + start: Column[datetime.datetime] = Column(UTCDateTime, nullable=False) + end: Column[datetime.datetime] = Column(UTCDateTime, nullable=False) + presenter_name: Column[str] = Column(Text, nullable=False) + presenter_company: Column[str] = Column(Text, nullable=False) + presenter_email: Column[str | None] = Column(Text) + min_attendees: Column[int] = Column( SmallInteger, nullable=False, default=1 ) - max_attendees: 'Column[int | None]' = Column(SmallInteger, nullable=True) + max_attendees: Column[int | None] = Column(SmallInteger, nullable=True) - status: 'Column[EventStatusType]' = Column( + status: Column[EventStatusType] = Column( Enum( # type:ignore[arg-type] *COURSE_EVENT_STATUSES, name='status' ), nullable=False, default='created') - attendees: 'relationship[AppenderQuery[CourseAttendee]]' = relationship( + attendees: relationship[AppenderQuery[CourseAttendee]] = relationship( CourseAttendee, secondary=subscription_table, primaryjoin=id == subscription_table.c.course_event_id, @@ -186,7 +188,7 @@ def localized_end(self) -> datetime.datetime: lazy='dynamic' ) - subscriptions: 'relationship[AppenderQuery[CourseSubscription]]' + subscriptions: relationship[AppenderQuery[CourseSubscription]] subscriptions = relationship( 'CourseSubscription', back_populates='course_event', @@ -194,7 +196,7 @@ def localized_end(self) -> datetime.datetime: cascade='all, delete-orphan', ) - notification_templates: 'relationship[list[CourseNotificationTemplate]]' + notification_templates: relationship[list[CourseNotificationTemplate]] notification_templates = relationship( 'CourseNotificationTemplate', back_populates='course_event', @@ -203,17 +205,17 @@ def localized_end(self) -> datetime.datetime: # The associated notification templates # FIXME: Are some of these optional? - info_template: 'relationship[InfoTemplate]' = relationship( + info_template: relationship[InfoTemplate] = relationship( 'InfoTemplate', uselist=False) - reservation_template: 'relationship[SubscriptionTemplate]' = relationship( + reservation_template: relationship[SubscriptionTemplate] = relationship( 'SubscriptionTemplate', uselist=False) - cancellation_template: 'relationship[CancellationTemplate]' = relationship( + cancellation_template: relationship[CancellationTemplate] = relationship( 'CancellationTemplate', uselist=False) - reminder_template: 'relationship[ReminderTemplate]' = relationship( + reminder_template: relationship[ReminderTemplate] = relationship( 'ReminderTemplate', uselist=False) # hides for members/editors - hidden_from_public: 'Column[bool]' = Column( + hidden_from_public: Column[bool] = Column( Boolean, nullable=False, default=False @@ -221,19 +223,19 @@ def localized_end(self) -> datetime.datetime: # to a locked event, only an admin can place subscriptions # FIXME: Is this intentionally nullable? - locked_for_subscriptions: 'Column[bool | None]' = Column( + locked_for_subscriptions: Column[bool | None] = Column( Boolean, default=False ) # when before course start schedule reminder email - schedule_reminder_before: 'Column[datetime.timedelta]' = Column( + schedule_reminder_before: Column[datetime.timedelta] = Column( Interval, nullable=False, default=default_reminder_before) @property - def description_html(self) -> 'Markup': + def description_html(self) -> Markup: """ Returns the portrait that is saved as HTML from the redactor js plugin. @@ -306,10 +308,10 @@ def duplicate_dict(self) -> dict[str, Any]: ) @property - def duplicate(self) -> 'Self': + def duplicate(self) -> Self: return self.__class__(**self.duplicate_dict) - def has_reservation(self, attendee_id: 'uuid.UUID') -> bool: + def has_reservation(self, attendee_id: uuid.UUID) -> bool: return self.subscriptions.filter_by( attendee_id=attendee_id).first() is not None @@ -319,7 +321,7 @@ def excluded_subscribers( year: int | None = None, as_uids: Literal[True] = True, exclude_inactive: bool = True - ) -> 'Query[tuple[uuid.UUID]]': ... + ) -> Query[tuple[uuid.UUID]]: ... @overload def excluded_subscribers( @@ -327,7 +329,7 @@ def excluded_subscribers( year: int | None, as_uids: Literal[False], exclude_inactive: bool = True - ) -> 'Query[CourseAttendee]': ... + ) -> Query[CourseAttendee]: ... @overload def excluded_subscribers( @@ -336,7 +338,7 @@ def excluded_subscribers( *, as_uids: Literal[False], exclude_inactive: bool = True - ) -> 'Query[CourseAttendee]': ... + ) -> Query[CourseAttendee]: ... @overload def excluded_subscribers( @@ -344,14 +346,14 @@ def excluded_subscribers( year: int | None, as_uids: bool, exclude_inactive: bool = True - ) -> 'Query[tuple[uuid.UUID]] | Query[CourseAttendee]': ... + ) -> Query[tuple[uuid.UUID]] | Query[CourseAttendee]: ... def excluded_subscribers( self, year: int | None = None, as_uids: bool = True, exclude_inactive: bool = True - ) -> 'Query[tuple[uuid.UUID]] | Query[CourseAttendee]': + ) -> Query[tuple[uuid.UUID]] | Query[CourseAttendee]: """ Returns a list of attendees / names tuple of UIDS of attendees that have booked one of the events of a course in @@ -393,7 +395,7 @@ def possible_subscribers( as_uids: Literal[False] = False, exclude_inactive: bool = True, auth_attendee: CourseAttendee | None = None - ) -> 'Query[CourseAttendee]': ... + ) -> Query[CourseAttendee]: ... @overload def possible_subscribers( @@ -403,7 +405,7 @@ def possible_subscribers( as_uids: Literal[True], exclude_inactive: bool = True, auth_attendee: CourseAttendee | None = None - ) -> 'Query[tuple[uuid.UUID]]': ... + ) -> Query[tuple[uuid.UUID]]: ... @overload def possible_subscribers( @@ -414,7 +416,7 @@ def possible_subscribers( as_uids: Literal[True], exclude_inactive: bool = True, auth_attendee: CourseAttendee | None = None - ) -> 'Query[tuple[uuid.UUID]]': ... + ) -> Query[tuple[uuid.UUID]]: ... def possible_subscribers( self, @@ -423,7 +425,7 @@ def possible_subscribers( as_uids: bool = False, exclude_inactive: bool = True, auth_attendee: CourseAttendee | None = None - ) -> 'Query[tuple[uuid.UUID]] | Query[CourseAttendee]': + ) -> Query[tuple[uuid.UUID]] | Query[CourseAttendee]: """Returns the list of possible bookers. Attendees that already have a subscription for the parent course in the same year are excluded.""" session = object_session(self) @@ -456,7 +458,7 @@ def possible_subscribers( return query @property - def email_recipients(self) -> 'Iterator[str]': + def email_recipients(self) -> Iterator[str]: return (att.email for att in self.attendees) def as_ical(self, event_url: str | None = None) -> bytes: @@ -491,7 +493,7 @@ def as_ical_attachment(self, url: str | None = None) -> Attachment: def can_book( self, - attendee_or_id: 'CourseAttendee | uuid.UUID | str', + attendee_or_id: CourseAttendee | uuid.UUID | str, year: int | None = None ) -> bool: diff --git a/src/onegov/fsi/models/course_notification_template.py b/src/onegov/fsi/models/course_notification_template.py index 8132f0b874..c4cc07dc2e 100644 --- a/src/onegov/fsi/models/course_notification_template.py +++ b/src/onegov/fsi/models/course_notification_template.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from uuid import uuid4 from markupsafe import Markup @@ -24,7 +26,7 @@ ] -NOTIFICATION_TYPES: tuple['NotificationType', ...] = ( +NOTIFICATION_TYPES: tuple[NotificationType, ...] = ( 'info', 'reservation', 'reminder', 'cancellation') NOTIFICATION_TYPE_TRANSLATIONS = ( _('Info Mail'), _('Subscription Confirmation'), @@ -42,7 +44,7 @@ # for forms... def template_type_choices( - request: 'FsiRequest | None' = None + request: FsiRequest | None = None ) -> tuple[tuple[str, str], ...]: if request: @@ -65,8 +67,8 @@ def get_template_default( def template_name( - type: 'NotificationType | Literal["invitation"]', - request: 'FsiRequest | None' = None + type: NotificationType | Literal['invitation'], + request: FsiRequest | None = None ) -> str: try: if type == 'invitation': @@ -106,7 +108,7 @@ class CourseNotificationTemplate(Base, ContentMixin, TimestampMixin): ) # the notification type used to choose the correct chameleon template - type: 'Column[NotificationType]' = Column( + type: Column[NotificationType] = Column( Enum(*NOTIFICATION_TYPES, name='notification_types'), # type:ignore nullable=False, ) @@ -117,34 +119,34 @@ class CourseNotificationTemplate(Base, ContentMixin, TimestampMixin): } # One-To-Many relationship with course - course_event_id: 'Column[uuid.UUID]' = Column( + course_event_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey('fsi_course_events.id'), nullable=False ) - course_event: 'relationship[CourseEvent]' = relationship( + course_event: relationship[CourseEvent] = relationship( 'CourseEvent', back_populates='notification_templates' ) #: The public id of the notification template - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: The subject of the notification would be according to template type - subject: 'Column[str | None]' = Column(Text, default=get_template_default) + subject: Column[str | None] = Column(Text, default=get_template_default) #: The body text injected in plaintext (not html) - text: 'Column[str | None]' = Column(Text) + text: Column[str | None] = Column(Text) # when email based on template was sent last time - last_sent: 'Column[datetime | None]' = Column(UTCDateTime) + last_sent: Column[datetime | None] = Column(UTCDateTime) - def duplicate(self) -> 'Self': + def duplicate(self) -> Self: return self.__class__( type=self.type, id=uuid4(), diff --git a/src/onegov/fsi/models/course_subscription.py b/src/onegov/fsi/models/course_subscription.py index 89d79ff50a..8c2e603a20 100644 --- a/src/onegov/fsi/models/course_subscription.py +++ b/src/onegov/fsi/models/course_subscription.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.types import UUID from sqlalchemy import Column, ForeignKey, Boolean, Table, Text @@ -53,12 +55,12 @@ class CourseSubscription(Base): event_completed: Column[bool] dummy_desc: Column[str | None] - course_event: 'relationship[CourseEvent]' = relationship( + course_event: relationship[CourseEvent] = relationship( 'CourseEvent', back_populates='subscriptions', lazy='joined' ) - attendee: 'relationship[CourseAttendee | None]' = relationship( + attendee: relationship[CourseAttendee | None] = relationship( 'CourseAttendee', back_populates='subscriptions', ) @@ -67,7 +69,7 @@ class CourseSubscription(Base): def is_placeholder(self) -> bool: return self.attendee_id is None - def can_be_confirmed(self, request: 'FsiRequest') -> bool: + def can_be_confirmed(self, request: FsiRequest) -> bool: if not request.is_admin: return False event = self.course_event diff --git a/src/onegov/fsi/path.py b/src/onegov/fsi/path.py index e1bce54add..a04ae7f058 100644 --- a/src/onegov/fsi/path.py +++ b/src/onegov/fsi/path.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import datetime from uuid import UUID @@ -24,7 +26,7 @@ @FsiApp.path(model=Course, path='/fsi/course/{id}', converters={'id': UUID}) -def get_course_details(request: 'FsiRequest', id: UUID) -> Course | None: +def get_course_details(request: FsiRequest, id: UUID) -> Course | None: return CourseCollection(request.session).by_id(id) @@ -34,7 +36,7 @@ def get_course_details(request: 'FsiRequest', id: UUID) -> Course | None: converters={'id': UUID} ) def get_course_event_details( - request: 'FsiRequest', + request: FsiRequest, id: UUID ) -> CourseEvent | None: return CourseEventCollection( @@ -54,7 +56,7 @@ def get_course_event_details( } ) def get_past_events_view( - request: 'FsiRequest', + request: FsiRequest, page: int = 0, show_hidden: bool = False, course_id: UUID | None = None, @@ -87,7 +89,7 @@ def get_past_events_view( } ) def get_events_view( - request: 'FsiRequest', + request: FsiRequest, page: int = 0, from_date: datetime | None = None, upcoming_only: bool = False, @@ -121,7 +123,7 @@ def get_events_view( converters={'show_hidden_from_public': bool} ) def get_courses( - request: 'FsiRequest', + request: FsiRequest, show_hidden_from_public: bool ) -> CourseCollection: @@ -146,7 +148,7 @@ def get_courses( } ) def get_attendees( - request: 'FsiRequest', + request: FsiRequest, page: int = 0, exclude_external: bool = False, external_only: bool = False, @@ -171,7 +173,7 @@ def get_attendees( converters={'id': UUID} ) def get_attendee_details( - request: 'FsiRequest', + request: FsiRequest, id: UUID ) -> CourseAttendee | None: return CourseAttendeeCollection(request.session).by_id(id) @@ -183,7 +185,7 @@ def get_attendee_details( converters={'course_event_id': UUID} ) def get_notification_templates( - request: 'FsiRequest', + request: FsiRequest, course_event_id: UUID | None = None ) -> CourseNotificationTemplateCollection: return CourseNotificationTemplateCollection( @@ -196,7 +198,7 @@ def get_notification_templates( converters={'id': UUID} ) def get_template_details( - request: 'FsiRequest', + request: FsiRequest, id: UUID ) -> CourseNotificationTemplate | None: return CourseNotificationTemplateCollection(request.session).by_id(id) @@ -212,7 +214,7 @@ def get_template_details( } ) def get_reservations( - request: 'FsiRequest', + request: FsiRequest, course_event_id: UUID | None = None, attendee_id: UUID | None = None, external_only: bool = False, @@ -243,7 +245,7 @@ def get_reservations( converters={'id': UUID} ) def get_reservation_details( - request: 'FsiRequest', + request: FsiRequest, id: UUID ) -> CourseSubscription | None: return SubscriptionsCollection(request.session).by_id(id) @@ -259,7 +261,7 @@ def get_reservation_details( } ) def get_audit( - request: 'FsiRequest', + request: FsiRequest, course_id: UUID | None, organisations: list[str], page: int = 0, diff --git a/src/onegov/fsi/pdf.py b/src/onegov/fsi/pdf.py index 58d2d5954e..4ebe5671fc 100644 --- a/src/onegov/fsi/pdf.py +++ b/src/onegov/fsi/pdf.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from io import BytesIO from operator import itemgetter @@ -28,11 +30,11 @@ class FsiPdf(Pdf): previous_level_context: int | None = None @property - def page_fn(self) -> 'Callable[[Canvas, Template], None]': + def page_fn(self) -> Callable[[Canvas, Template], None]: return page_fn_footer @property - def page_fn_later(self) -> 'Callable[[Canvas, Template], None]': + def page_fn_later(self) -> Callable[[Canvas, Template], None]: return page_fn_header_and_footer @property @@ -46,8 +48,8 @@ def table_style(self) -> list[tuple[Any, ...]]: @classmethod def from_subscriptions( cls, - collection: 'SubscriptionsCollection', - layout: 'DefaultLayout', + collection: SubscriptionsCollection, + layout: DefaultLayout, title: str ) -> BytesIO: @@ -78,7 +80,7 @@ def get_headers() -> list[str]: headers += ['Course Status', 'Course attended', 'Last info mail'] return [translate(_(h)) for h in headers] - def get_row(subscription: 'CourseSubscription') -> list[str]: + def get_row(subscription: CourseSubscription) -> list[str]: row = [str(subscription)] att = subscription.attendee row.append(att and att.source_id or '') @@ -119,8 +121,8 @@ def get_row(subscription: 'CourseSubscription') -> list[str]: @classmethod def from_audit_collection( cls, - collection: 'AuditCollection', - layout: 'AuditLayout', + collection: AuditCollection, + layout: AuditLayout, title: str ) -> BytesIO: @@ -171,7 +173,7 @@ def from_audit_collection( style = pdf.table_style - def bgcolor(ix: int, row: int, color: 'Color') -> tuple[Any, ...]: + def bgcolor(ix: int, row: int, color: Color) -> tuple[Any, ...]: return 'BACKGROUND', (row, ix), (row, ix), color next_subscriptions = collection.next_subscriptions(request) diff --git a/src/onegov/fsi/request.py b/src/onegov/fsi/request.py index 2a8bfa60d2..4d8b48d5c8 100644 --- a/src/onegov/fsi/request.py +++ b/src/onegov/fsi/request.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.town6.request import TownRequest @@ -11,7 +13,7 @@ class FsiRequest(TownRequest): @cached_property - def attendee(self) -> 'CourseAttendee | None': + def attendee(self) -> CourseAttendee | None: return ( # FIXME: backref across module boundaries self.current_user.attendee # type:ignore[attr-defined] @@ -19,7 +21,7 @@ def attendee(self) -> 'CourseAttendee | None': ) @cached_property - def attendee_id(self) -> 'UUID | None': + def attendee_id(self) -> UUID | None: return self.attendee.id if self.attendee else None @cached_property diff --git a/src/onegov/fsi/security.py b/src/onegov/fsi/security.py index 475bccfc48..fd522c26c0 100644 --- a/src/onegov/fsi/security.py +++ b/src/onegov/fsi/security.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Personal from onegov.core.security.rules import has_permission_logged_in from onegov.fsi import FsiApp @@ -25,7 +27,7 @@ @FsiApp.permission_rule(model=object, permission=Personal) def local_is_logged_in( app: FsiApp, - identity: 'Identity', + identity: Identity, model: object, permission: type[Personal] ) -> bool: @@ -35,7 +37,7 @@ def local_is_logged_in( @FsiApp.permission_rule(model=CourseAttendee, permission=Personal) def has_course_attendee_permission( app: FsiApp, - identity: 'Identity', + identity: Identity, model: CourseAttendee, permission: type[Personal] ) -> bool: diff --git a/src/onegov/fsi/theme/__init__.py b/src/onegov/fsi/theme/__init__.py index 326d757068..a5f4567b23 100644 --- a/src/onegov/fsi/theme/__init__.py +++ b/src/onegov/fsi/theme/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import module_path from onegov.town6.theme import TownTheme diff --git a/src/onegov/fsi/upgrade.py b/src/onegov/fsi/upgrade.py index 99ff6b90c4..bb092c844d 100644 --- a/src/onegov/fsi/upgrade.py +++ b/src/onegov/fsi/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + import textwrap from sqlalchemy import Column, ARRAY, Text, Boolean diff --git a/src/onegov/fsi/utils.py b/src/onegov/fsi/utils.py index 4c6c7c3b1b..18d271bcda 100644 --- a/src/onegov/fsi/utils.py +++ b/src/onegov/fsi/utils.py @@ -1,2 +1,5 @@ +from __future__ import annotations + + def handle_empty_p_tags(html: str) -> str: return html if html != '

' else '' diff --git a/src/onegov/fsi/views/attendee.py b/src/onegov/fsi/views/attendee.py index cd50d63be1..1cb3b95bc4 100644 --- a/src/onegov/fsi/views/attendee.py +++ b/src/onegov/fsi/views/attendee.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Private, Personal, Secret from onegov.fsi import FsiApp from onegov.fsi.collections.attendee import CourseAttendeeCollection @@ -25,8 +27,8 @@ ) def view_course_attendee_collection( self: CourseAttendeeCollection, - request: 'FsiRequest' -) -> 'RenderData': + request: FsiRequest +) -> RenderData: layout = CourseAttendeeCollectionLayout(self, request) has_entries = request.session.query(self.query().exists()).scalar() @@ -45,16 +47,16 @@ def view_course_attendee_collection( ) def view_course_attendee( self: CourseAttendee, - request: 'FsiRequest' -) -> 'RenderData': + request: FsiRequest +) -> RenderData: layout = CourseAttendeeLayout(self, request) limit = 5 def last_subscriptions( - query: 'Query[CourseSubscription]', + query: Query[CourseSubscription], limit: int - ) -> list['CourseSubscription']: + ) -> list[CourseSubscription]: return ( query.join(CourseEvent) .order_by(CourseEvent.start.desc()) @@ -79,9 +81,9 @@ def last_subscriptions( ) def view_edit_course_attendee( self: CourseAttendee, - request: 'FsiRequest', + request: FsiRequest, form: CourseAttendeeForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): @@ -111,9 +113,9 @@ def view_edit_course_attendee( ) def view_add_external_attendee( self: CourseAttendeeCollection, - request: 'FsiRequest', + request: FsiRequest, form: AddExternalAttendeeForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): attendee = self.add(**form.get_useful_data()) @@ -136,7 +138,7 @@ def view_add_external_attendee( ) def view_delete_reservation( self: CourseAttendee, - request: 'FsiRequest' + request: FsiRequest ) -> None: request.assert_valid_csrf_token() diff --git a/src/onegov/fsi/views/audit.py b/src/onegov/fsi/views/audit.py index 7e27755e91..29d640a3d6 100644 --- a/src/onegov/fsi/views/audit.py +++ b/src/onegov/fsi/views/audit.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.elements import Link from onegov.core.security import Private from onegov.fsi import _ @@ -18,14 +20,14 @@ def set_cached_choices( - request: 'FsiRequest', + request: FsiRequest, organisations: list[str] | None ) -> None: browser_session = request.browser_session browser_session['last_chosen_organisations'] = organisations or None -def cached_org_choices(request: 'FsiRequest') -> list[str] | None: +def cached_org_choices(request: FsiRequest) -> list[str] | None: return request.browser_session.get('last_chosen_organisations') @@ -37,9 +39,9 @@ def cached_org_choices(request: 'FsiRequest') -> list[str] | None: ) def invite_attendees_for_event( self: AuditCollection, - request: 'FsiRequest', + request: FsiRequest, form: AuditForm -) -> 'RenderData | Response': +) -> RenderData | Response: now = utcnow() @@ -115,7 +117,7 @@ def invite_attendees_for_event( name='pdf', permission=Private ) -def get_audit_pdf(self: AuditCollection, request: 'FsiRequest') -> Response: +def get_audit_pdf(self: AuditCollection, request: FsiRequest) -> Response: if not self.course_id: # FIXME: Really, a 503 for this? return Response(status='503 Service Unavailable') diff --git a/src/onegov/fsi/views/course.py b/src/onegov/fsi/views/course.py index 5d85f6c339..7aa8efd264 100644 --- a/src/onegov/fsi/views/course.py +++ b/src/onegov/fsi/views/course.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Private, Secret, Personal from onegov.core.templates import render_template from onegov.fsi import FsiApp @@ -26,10 +28,10 @@ def handle_send_invitation_email( self: CourseInvitationTemplate, course: Course, - request: 'FsiRequest', - recipients: 'Collection[str]', + request: FsiRequest, + recipients: Collection[str], cc_to_sender: bool = True -) -> 'FsiRequest': +) -> FsiRequest: """Recipients must be a list of emails""" if not recipients: @@ -46,7 +48,7 @@ def handle_send_invitation_email( errors = [] - def email_iter() -> 'Iterator[EmailJsonDict]': + def email_iter() -> Iterator[EmailJsonDict]: for email in recipients: attendee = request.session.query( @@ -102,8 +104,8 @@ def email_iter() -> 'Iterator[EmailJsonDict]': ) def view_email_preview_for_course( self: Course, - request: 'FsiRequest' -) -> 'RenderData': + request: FsiRequest +) -> RenderData: mail_layout = CourseInviteMailLayout(self, request) @@ -124,8 +126,8 @@ def view_email_preview_for_course( ) def view_course_collection( self: CourseCollection, - request: 'FsiRequest' -) -> 'RenderData': + request: FsiRequest +) -> RenderData: layout = CourseCollectionLayout(self, request) return { 'layout': layout, @@ -142,9 +144,9 @@ def view_course_collection( ) def view_add_course_event( self: CourseCollection, - request: 'FsiRequest', + request: FsiRequest, form: CourseForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): course = self.add(**form.get_useful_data()) @@ -166,7 +168,7 @@ def view_add_course_event( template='course.pt', permission=Personal ) -def view_course_event(self: Course, request: 'FsiRequest') -> 'RenderData': +def view_course_event(self: Course, request: FsiRequest) -> RenderData: layout = CourseLayout(self, request) return { 'layout': layout, @@ -180,7 +182,7 @@ def view_course_event(self: Course, request: 'FsiRequest') -> 'RenderData': permission=Personal, name='content-json' ) -def get_course_event_content(self: Course, request: 'FsiRequest') -> str: +def get_course_event_content(self: Course, request: FsiRequest) -> str: return self.description_html @@ -193,9 +195,9 @@ def get_course_event_content(self: Course, request: 'FsiRequest') -> str: ) def view_edit_course_event( self: Course, - request: 'FsiRequest', + request: FsiRequest, form: CourseForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): form.update_model(self) @@ -226,9 +228,9 @@ def view_edit_course_event( ) def invite_attendees_for_event( self: Course, - request: 'FsiRequest', + request: FsiRequest, form: InviteCourseForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): recipients = form.get_useful_data() @@ -258,7 +260,7 @@ def invite_attendees_for_event( request_method='DELETE', permission=Secret ) -def delete_course(self: Course, request: 'FsiRequest') -> None: +def delete_course(self: Course, request: FsiRequest) -> None: request.assert_valid_csrf_token() if not request.session.query(self.events.exists()).scalar(): CourseCollection(request.session).delete(self) diff --git a/src/onegov/fsi/views/course_event.py b/src/onegov/fsi/views/course_event.py index 593c4c84a3..9e19adfc44 100644 --- a/src/onegov/fsi/views/course_event.py +++ b/src/onegov/fsi/views/course_event.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Personal, Secret from onegov.core.templates import render_macro from onegov.fsi import FsiApp @@ -26,8 +28,8 @@ ) def view_course_event_collection( self: CourseEventCollection, - request: 'FsiRequest' -) -> 'RenderData': + request: FsiRequest +) -> RenderData: layout = CourseEventCollectionLayout(self, request) has_events = request.session.query(self.query().exists()).scalar() @@ -45,7 +47,7 @@ def view_course_event_collection( ) def view_course_event_collection_json( self: CourseEventCollection, - request: 'FsiRequest' + request: FsiRequest ) -> str: layout = CourseEventCollectionLayout(self, request) @@ -67,8 +69,8 @@ def view_course_event_collection_json( ) def view_past_course_event_collection( self: PastCourseEventCollection, - request: 'FsiRequest' -) -> 'RenderData': + request: FsiRequest +) -> RenderData: layout = CourseEventCollectionLayout(self, request) return { 'layout': layout, @@ -86,9 +88,9 @@ def view_past_course_event_collection( ) def view_add_course_event( self: CourseEventCollection, - request: 'FsiRequest', + request: FsiRequest, form: CourseEventForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): course_event = self.add(**form.get_useful_data()) @@ -111,8 +113,8 @@ def view_add_course_event( ) def view_course_event( self: CourseEvent, - request: 'FsiRequest' -) -> 'RenderData': + request: FsiRequest +) -> RenderData: layout = CourseEventLayout(self, request) return { @@ -130,9 +132,9 @@ def view_course_event( ) def view_edit_course_event( self: CourseEvent, - request: 'FsiRequest', + request: FsiRequest, form: CourseEventForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): form.update_model(self) @@ -161,9 +163,9 @@ def view_edit_course_event( ) def view_duplicate_course_event( self: CourseEvent, - request: 'FsiRequest', + request: FsiRequest, form: CourseEventForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): duplicate = CourseEventCollection( @@ -187,7 +189,7 @@ def view_duplicate_course_event( request_method='DELETE', permission=Secret ) -def delete_course_event(self: CourseEvent, request: 'FsiRequest') -> None: +def delete_course_event(self: CourseEvent, request: FsiRequest) -> None: request.assert_valid_csrf_token() if not self.subscriptions.first(): CourseEventCollection(request.session).delete(self) @@ -202,7 +204,7 @@ def delete_course_event(self: CourseEvent, request: 'FsiRequest') -> None: permission=Secret, name='cancel' ) -def cancel_course_event(self: CourseEvent, request: 'FsiRequest') -> None: +def cancel_course_event(self: CourseEvent, request: FsiRequest) -> None: request.assert_valid_csrf_token() self.status = 'canceled' diff --git a/src/onegov/fsi/views/login.py b/src/onegov/fsi/views/login.py index abb581bced..749a5e9ec5 100644 --- a/src/onegov/fsi/views/login.py +++ b/src/onegov/fsi/views/login.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Public from onegov.fsi import _ from onegov.fsi.app import FsiApp @@ -17,7 +19,7 @@ class FsiLoginForm(LoginForm): @property - def login_data(self) -> 'LoginData': + def login_data(self) -> LoginData: """ Skips auth providers for school users are just indexed by the LDAP but not can bot be logged in to. The are authenticated with the user and @@ -48,9 +50,9 @@ def login_data(self) -> 'LoginData': ) def handle_login( self: Auth, - request: 'FsiRequest', + request: FsiRequest, form: FsiLoginForm -) -> 'RenderData | Response': +) -> RenderData | Response: # custom default redirect if self.to == '/': diff --git a/src/onegov/fsi/views/notifcations.py b/src/onegov/fsi/views/notifcations.py index 14a6a85b4f..b1e160da59 100644 --- a/src/onegov/fsi/views/notifcations.py +++ b/src/onegov/fsi/views/notifcations.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Secret from onegov.core.templates import render_template from onegov.fsi import FsiApp @@ -28,12 +30,12 @@ def handle_send_email( self: CourseNotificationTemplate, - request: 'FsiRequest', - recipients: 'Sequence[UUID] | Sequence[CourseAttendee]', + request: FsiRequest, + recipients: Sequence[UUID] | Sequence[CourseAttendee], cc_to_sender: bool = True, show_sent_count: bool = True, - attachments: 'Iterable[Attachment | StrPath] | None' = None -) -> 'FsiRequest': + attachments: Iterable[Attachment | StrPath] | None = None +) -> FsiRequest: """Recipients must be a list of attendee id's or attendees""" if not recipients: @@ -57,7 +59,7 @@ def handle_send_email( mail_layout = MailLayout(self, request) - def email_iter() -> 'Iterator[EmailJsonDict]': + def email_iter() -> Iterator[EmailJsonDict]: for attendee in recipients: content = render_template('mail_notification.pt', request, { 'layout': mail_layout, @@ -94,8 +96,8 @@ def email_iter() -> 'Iterator[EmailJsonDict]': ) def view_notifications( self: CourseNotificationTemplateCollection, - request: 'FsiRequest' -) -> 'RenderData': + request: FsiRequest +) -> RenderData: layout = NotificationTemplateCollectionLayout(self, request) # This was a workaround and should be removed in the future @@ -115,8 +117,8 @@ def view_notifications( ) def view_notification_details( self: CourseNotificationTemplate, - request: 'FsiRequest' -) -> 'RenderData': + request: FsiRequest +) -> RenderData: return { 'layout': NotificationTemplateLayout(self, request) } @@ -131,9 +133,9 @@ def view_notification_details( ) def view_edit_notification( self: CourseNotificationTemplate, - request: 'FsiRequest', + request: FsiRequest, form: NotificationForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): form.update_model(self) @@ -160,8 +162,8 @@ def view_edit_notification( ) def view_email_preview( self: CourseNotificationTemplate, - request: 'FsiRequest' -) -> 'RenderData': + request: FsiRequest +) -> RenderData: layout = MailLayout(self, request) @@ -183,9 +185,9 @@ def view_email_preview( ) def handle_send_notification( self: CourseNotificationTemplate, - request: 'FsiRequest', + request: FsiRequest, form: NotificationTemplateSendForm -) -> 'RenderData | Response': +) -> RenderData | Response: layout = SendNotificationTemplateLayout(self, request) diff --git a/src/onegov/fsi/views/search.py b/src/onegov/fsi/views/search.py index e915c4cec3..1d552356f4 100644 --- a/src/onegov/fsi/views/search.py +++ b/src/onegov/fsi/views/search.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Personal from onegov.fsi import FsiApp from onegov.org.models import Search @@ -15,15 +17,15 @@ @FsiApp.html(model=Search, template='search.pt', permission=Personal) def search( - self: Search['Base'], - request: 'FsiRequest' -) -> 'RenderData | Response': + self: Search[Base], + request: FsiRequest +) -> RenderData | Response: return search_view(self, request) @FsiApp.json(model=Search, name='suggest', permission=Personal) def suggestions( - self: Search['Base'], - request: 'FsiRequest' -) -> 'JSON_ro': + self: Search[Base], + request: FsiRequest +) -> JSON_ro: return suggestions_view(self, request) diff --git a/src/onegov/fsi/views/subscription.py b/src/onegov/fsi/views/subscription.py index 61f48d9c9b..20eaa38977 100644 --- a/src/onegov/fsi/views/subscription.py +++ b/src/onegov/fsi/views/subscription.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from webob import Response from webob.exc import HTTPForbidden @@ -29,8 +31,8 @@ ) def view_subscriptions( self: SubscriptionsCollection, - request: 'FsiRequest' -) -> 'RenderData': + request: FsiRequest +) -> RenderData: layout = SubscriptionCollectionLayout(self, request) return { 'layout': layout, @@ -45,7 +47,7 @@ def view_subscriptions( ) def attendee_list_as_pdf( self: SubscriptionsCollection, - request: 'FsiRequest' + request: FsiRequest ) -> Response: layout = SubscriptionCollectionLayout(self, request) @@ -70,9 +72,9 @@ def attendee_list_as_pdf( ) def view_add_reservation( self: SubscriptionsCollection, - request: 'FsiRequest', + request: FsiRequest, form: AddFsiSubscriptionForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): data = form.get_useful_data() @@ -118,9 +120,9 @@ def view_add_reservation( ) def view_edit_reservation( self: CourseSubscription, - request: 'FsiRequest', + request: FsiRequest, form: EditFsiSubscriptionForm -) -> 'RenderData | Response': +) -> RenderData | Response: if self.is_placeholder: raise HTTPForbidden() @@ -185,9 +187,9 @@ def view_edit_reservation( ) def view_edit_placeholder_reservation( self: CourseSubscription, - request: 'FsiRequest', + request: FsiRequest, form: EditFsiPlaceholderSubscriptionForm -) -> 'RenderData | Response': +) -> RenderData | Response: if not self.is_placeholder: raise HTTPForbidden() @@ -223,9 +225,9 @@ def view_edit_placeholder_reservation( ) def view_add_reservation_placeholder( self: SubscriptionsCollection, - request: 'FsiRequest', + request: FsiRequest, form: AddFsiPlaceholderSubscriptionForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): data = form.get_useful_data() @@ -262,7 +264,7 @@ def view_add_reservation_placeholder( ) def view_add_from_course_event( self: SubscriptionsCollection, - request: 'FsiRequest' + request: FsiRequest ) -> None: if self.course_event is None or self.attendee is None: @@ -290,7 +292,7 @@ def view_add_from_course_event( ) def view_delete_reservation( self: CourseSubscription, - request: 'FsiRequest' + request: FsiRequest ) -> None: request.assert_valid_csrf_token() @@ -318,7 +320,7 @@ def view_delete_reservation( ) def view_toggle_confirm_reservation( self: CourseSubscription, - request: 'FsiRequest' + request: FsiRequest ) -> bool: request.assert_valid_csrf_token() self.event_completed = not self.event_completed diff --git a/src/onegov/gazette/__init__.py b/src/onegov/gazette/__init__.py index ebcf90e32e..0f7d4dd2f9 100644 --- a/src/onegov/gazette/__init__.py +++ b/src/onegov/gazette/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.gazette') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/gazette/app.py b/src/onegov/gazette/app.py index 9fc833d053..87d38a3b30 100644 --- a/src/onegov/gazette/app.py +++ b/src/onegov/gazette/app.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from more.content_security import UNSAFE_EVAL from more.content_security import UNSAFE_INLINE from onegov.core import Framework, utils @@ -138,7 +140,7 @@ def get_i18n_default_locale() -> str: @GazetteApp.setting(section='content_security_policy', name='default') -def get_content_security_policy() -> 'ContentSecurityPolicy': +def get_content_security_policy() -> ContentSecurityPolicy: policy = default_content_security_policy() policy.script_src.remove(UNSAFE_EVAL) policy.script_src.remove(UNSAFE_INLINE) @@ -169,7 +171,7 @@ def get_webasset_output() -> str: 'frameworks', filters={'css': ['datauri', 'custom-rcssmin']} ) -def get_frameworks_asset() -> 'Iterator[str]': +def get_frameworks_asset() -> Iterator[str]: # common assets unlikely to change yield 'modernizr.js' @@ -191,7 +193,7 @@ def get_frameworks_asset() -> 'Iterator[str]': @GazetteApp.webasset('common') -def get_common_asset() -> 'Iterator[str]': +def get_common_asset() -> Iterator[str]: # custom code yield 'form_dependencies.js' yield 'datetimepicker.js' diff --git a/src/onegov/gazette/cli.py b/src/onegov/gazette/cli.py index 54e9ea3f02..9919596385 100644 --- a/src/onegov/gazette/cli.py +++ b/src/onegov/gazette/cli.py @@ -1,4 +1,5 @@ """ Provides commands used to initialize gazette websites. """ +from __future__ import annotations import click import transaction @@ -37,8 +38,8 @@ @cli.command(context_settings={'creates_path': True}) @pass_group_context def add( - group_context: 'GroupContext' -) -> 'Callable[[GazetteRequest, GazetteApp], None]': + group_context: GroupContext +) -> Callable[[GazetteRequest, GazetteApp], None]: """ Adds a gazette instance to the database. For example: .. code-block:: bash @@ -47,7 +48,7 @@ def add( """ - def add_instance(request: 'GazetteRequest', app: 'GazetteApp') -> None: + def add_instance(request: GazetteRequest, app: GazetteApp) -> None: if not app.principal: click.secho('principal.yml not found', fg='yellow') click.echo('Instance was created successfully') @@ -62,12 +63,12 @@ def add_instance(request: 'GazetteRequest', app: 'GazetteApp') -> None: @click.option('--locale', default='de_CH') @pass_group_context def import_editors( - group_context: 'GroupContext', + group_context: GroupContext, file: IO[bytes], clear: bool, dry_run: bool, locale: str -) -> 'Callable[[GazetteRequest, GazetteApp], None]': +) -> Callable[[GazetteRequest, GazetteApp], None]: """ Imports editors and groups. For example: .. code-block:: bash @@ -77,8 +78,8 @@ def import_editors( """ def import_editors_and_groups( - request: 'GazetteRequest', - app: 'GazetteApp' + request: GazetteRequest, + app: GazetteApp ) -> None: request.locale = locale @@ -148,12 +149,12 @@ def import_editors_and_groups( @click.option('--locale', default='de_CH') @pass_group_context def import_organizations( - group_context: 'GroupContext', + group_context: GroupContext, file: IO[bytes], clear: bool, dry_run: bool, locale: str -) -> 'Callable[[GazetteRequest, GazetteApp], None]': +) -> Callable[[GazetteRequest, GazetteApp], None]: r""" Imports Organizations. For example: .. code-block:: bash @@ -164,8 +165,8 @@ def import_organizations( """ def _import_organizations( - request: 'GazetteRequest', - app: 'GazetteApp' + request: GazetteRequest, + app: GazetteApp ) -> None: request.locale = locale @@ -233,12 +234,12 @@ def _import_organizations( @click.option('--locale', default='de_CH') @pass_group_context def import_categories( - group_context: 'GroupContext', + group_context: GroupContext, file: IO[bytes], clear: bool, dry_run: bool, locale: str -) -> 'Callable[[GazetteRequest, GazetteApp], None]': +) -> Callable[[GazetteRequest, GazetteApp], None]: r""" Imports categories. For example: .. code-block:: bash @@ -249,8 +250,8 @@ def import_categories( """ def _import_categories( - request: 'GazetteRequest', - app: 'GazetteApp' + request: GazetteRequest, + app: GazetteApp ) -> None: request.locale = locale @@ -311,13 +312,13 @@ def _import_categories( @click.option('--timezone', default=None) @pass_group_context def import_issues( - group_context: 'GroupContext', + group_context: GroupContext, file: IO[bytes], clear: bool, dry_run: bool, locale: str, timezone: str | None -) -> 'Callable[[GazetteRequest, GazetteApp], None]': +) -> Callable[[GazetteRequest, GazetteApp], None]: """ Imports issues. For example: .. code-block:: bash @@ -327,8 +328,8 @@ def import_issues( """ def _import_issues( - request: 'GazetteRequest', - app: 'GazetteApp' + request: GazetteRequest, + app: GazetteApp ) -> None: if not app.principal: @@ -391,10 +392,10 @@ def _import_issues( @click.option('--dry-run/--no-dry-run', default=False) @pass_group_context def import_sogc( - group_context: 'GroupContext', + group_context: GroupContext, clear: bool, dry_run: bool -) -> 'Callable[[GazetteRequest, GazetteApp], None]': +) -> Callable[[GazetteRequest, GazetteApp], None]: """ Imports from the SOGC. For example: .. code-block:: bash @@ -404,8 +405,8 @@ def import_sogc( """ def _import_sogc( - request: 'GazetteRequest', - app: 'GazetteApp' + request: GazetteRequest, + app: GazetteApp ) -> None: if not app.principal: diff --git a/src/onegov/gazette/collections/__init__.py b/src/onegov/gazette/collections/__init__.py index dea62b8bf2..3394cbb622 100644 --- a/src/onegov/gazette/collections/__init__.py +++ b/src/onegov/gazette/collections/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.gazette.collections.categories import CategoryCollection from onegov.gazette.collections.issues import IssueCollection from onegov.gazette.collections.notices import GazetteNoticeCollection diff --git a/src/onegov/gazette/collections/categories.py b/src/onegov/gazette/collections/categories.py index abb1571129..d493a4fa9f 100644 --- a/src/onegov/gazette/collections/categories.py +++ b/src/onegov/gazette/collections/categories.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.abstract import AdjacencyListCollection from onegov.gazette.models import Category diff --git a/src/onegov/gazette/collections/issues.py b/src/onegov/gazette/collections/issues.py index 2faffa6fd6..5c47ebca40 100644 --- a/src/onegov/gazette/collections/issues.py +++ b/src/onegov/gazette/collections/issues.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from onegov.core.collection import GenericCollection from onegov.gazette.models import Issue @@ -16,7 +18,7 @@ class IssueCollection(GenericCollection[Issue]): def model_class(self) -> type[Issue]: return Issue - def query(self) -> 'Query[Issue]': + def query(self) -> Query[Issue]: query = super().query() query = query.order_by(None).order_by(Issue.date) return query diff --git a/src/onegov/gazette/collections/notices.py b/src/onegov/gazette/collections/notices.py index 82b9d584dd..b84d312768 100644 --- a/src/onegov/gazette/collections/notices.py +++ b/src/onegov/gazette/collections/notices.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from itertools import groupby from onegov.chat import MessageCollection from onegov.core.utils import groupbylist @@ -57,20 +59,20 @@ def model_class(self) -> type[GazetteNotice]: def __init__( self, - session: 'Session', + session: Session, page: int = 0, - state: 'NoticeState | None' = None, + state: NoticeState | None = None, term: str | None = None, order: str | None = None, direction: Literal['asc', 'desc'] | None = None, - issues: 'Collection[str] | None ' = None, - categories: 'Collection[str] | None ' = None, - organizations: 'Collection[str] | None ' = None, - user_ids: list['UUID'] | None = None, - group_ids: list['UUID'] | None = None, - from_date: 'date | None' = None, - to_date: 'date | None' = None, - source: 'UUID | None' = None, + issues: Collection[str] | None = None, + categories: Collection[str] | None = None, + organizations: Collection[str] | None = None, + user_ids: list[UUID] | None = None, + group_ids: list[UUID] | None = None, + from_date: date | None = None, + to_date: date | None = None, + source: UUID | None = None, own: bool | None = None ) -> None: @@ -102,13 +104,13 @@ def __init__( self.own = own self.own_user_id: str | None = None - def on_request(self, request: 'GazetteRequest') -> None: + def on_request(self, request: GazetteRequest) -> None: if self.own and request.identity and request.identity.userid: id_ = self.session.query(User.id) row = id_.filter_by(username=request.identity.userid).first() self.own_user_id = str(row[0]) if row else None - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__( self.session, page=index, @@ -127,7 +129,7 @@ def page_by_index(self, index: int) -> 'Self': own=self.own ) - def for_state(self, state: 'NoticeState') -> 'Self': + def for_state(self, state: NoticeState) -> Self: """ Returns a new instance of the collection with the given state. """ result = super().for_state(state) @@ -137,7 +139,7 @@ def for_state(self, state: 'NoticeState') -> 'Self': result.own = self.own return result - def for_term(self, term: str | None) -> 'Self': + def for_term(self, term: str | None) -> Self: """ Returns a new instance of the collection with the given term. """ result = super().for_term(term) @@ -151,7 +153,7 @@ def for_order( self, order: str, direction: Literal['asc', 'desc'] | None = None - ) -> 'Self': + ) -> Self: """ Returns a new instance of the collection with the given ordering. Inverts the direction if the new ordering is the same as the old one and an explicit ordering is not defined. @@ -167,8 +169,8 @@ def for_order( def for_organizations( self, - organizations: 'Collection[str] | None' - ) -> 'Self': + organizations: Collection[str] | None + ) -> Self: """ Returns a new instance of the collection with the given organizations. @@ -181,7 +183,7 @@ def for_organizations( result.own = self.own return result - def for_categories(self, categories: 'Collection[str] | None') -> 'Self': + def for_categories(self, categories: Collection[str] | None) -> Self: """ Returns a new instance of the collection with the given categories. """ @@ -195,9 +197,9 @@ def for_categories(self, categories: 'Collection[str] | None') -> 'Self': def for_dates( self, - from_date: 'date | None', - to_date: 'date | None' - ) -> 'Self': + from_date: date | None, + to_date: date | None + ) -> Self: """ Returns a new instance of the collection with the given dates. """ return self.__class__( @@ -217,7 +219,7 @@ def for_dates( ) @property - def term_columns(self) -> list['_StrColumnLike']: + def term_columns(self) -> list[_StrColumnLike]: """ The columns used for full text search. """ return [ @@ -228,8 +230,8 @@ def term_columns(self) -> list['_StrColumnLike']: def filter_query( self, - query: 'Query[GazetteNotice]' - ) -> 'Query[GazetteNotice]': + query: Query[GazetteNotice] + ) -> Query[GazetteNotice]: """ Allows additionally to filter for notices with changes made by a given user. @@ -253,7 +255,7 @@ def add( # type: ignore[override] organization_id: str | None, category_id: str | None, user: User, - issues: 'dict[str, str | None] | Iterable[str]', + issues: dict[str, str | None] | Iterable[str], **kwargs: Any ) -> GazetteNotice: """ Add a new notice. @@ -325,7 +327,7 @@ def count_by_organization(self) -> list[tuple[str, int]]: # while issues.union also works it doesn't convey the # intent very well, that we just count the original # issues without filtering them - def operation(x: list[str]) -> 'Sized': + def operation(x: list[str]) -> Sized: return x return [ ( @@ -367,7 +369,7 @@ def count_by_category(self) -> list[tuple[str, int]]: # while issues.union also works it doesn't convey the # intent very well, that we just count the original # issues without filtering them - def operation(x: list[str]) -> 'Sized': + def operation(x: list[str]) -> Sized: return x return [ ( @@ -409,7 +411,7 @@ def count_by_group(self) -> list[tuple[str, int]]: # while issues.union also works it doesn't convey the # intent very well, that we just count the original # issues without filtering them - def operation(x: list[str]) -> 'Sized': + def operation(x: list[str]) -> Sized: return x return [ ( diff --git a/src/onegov/gazette/collections/organizations.py b/src/onegov/gazette/collections/organizations.py index 974906936d..eb67d6b650 100644 --- a/src/onegov/gazette/collections/organizations.py +++ b/src/onegov/gazette/collections/organizations.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.abstract import AdjacencyListCollection from onegov.gazette.models import Organization diff --git a/src/onegov/gazette/fields.py b/src/onegov/gazette/fields.py index 1caf70b025..f1f8d9ed83 100644 --- a/src/onegov/gazette/fields.py +++ b/src/onegov/gazette/fields.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form.fields import MultiCheckboxField as MultiCheckboxFieldBase from onegov.form.widgets import MultiCheckboxWidget as MultiCheckboxWidgetBase from onegov.gazette import _ @@ -13,9 +15,9 @@ class MultiCheckboxWidget(MultiCheckboxWidgetBase): def __call__( self, - field: 'MultiCheckboxField', # type:ignore[override] + field: MultiCheckboxField, # type:ignore[override] **kwargs: Any - ) -> 'Markup': + ) -> Markup: kwargs['data-expand-title'] = field.gettext(_('Show all')) kwargs['data-fold-title'] = field.gettext(_('Show less')) diff --git a/src/onegov/gazette/forms/__init__.py b/src/onegov/gazette/forms/__init__.py index 7c4fd093a5..4ca76b4375 100644 --- a/src/onegov/gazette/forms/__init__.py +++ b/src/onegov/gazette/forms/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.gazette.forms.category import CategoryForm from onegov.gazette.forms.common import EmptyForm from onegov.gazette.forms.common import RejectForm diff --git a/src/onegov/gazette/forms/category.py b/src/onegov/gazette/forms/category.py index 5dbb91b431..70a39d720a 100644 --- a/src/onegov/gazette/forms/category.py +++ b/src/onegov/gazette/forms/category.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.form.validators import UniqueColumnValue from onegov.gazette import _ diff --git a/src/onegov/gazette/forms/common.py b/src/onegov/gazette/forms/common.py index 96cd5505e0..d2580eb7d7 100644 --- a/src/onegov/gazette/forms/common.py +++ b/src/onegov/gazette/forms/common.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.gazette import _ from wtforms.fields import TextAreaField diff --git a/src/onegov/gazette/forms/issue.py b/src/onegov/gazette/forms/issue.py index de61ccc45b..b14737dcca 100644 --- a/src/onegov/gazette/forms/issue.py +++ b/src/onegov/gazette/forms/issue.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.form.fields import DateTimeLocalField from onegov.form.validators import UniqueColumnValue @@ -22,7 +24,7 @@ class IssueForm(Form): - request: 'GazetteRequest' + request: GazetteRequest number = IntegerField( label=_('Number'), diff --git a/src/onegov/gazette/forms/notice.py b/src/onegov/gazette/forms/notice.py index 0b662f1f75..2b152679a5 100644 --- a/src/onegov/gazette/forms/notice.py +++ b/src/onegov/gazette/forms/notice.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from datetime import datetime from markupsafe import Markup @@ -40,7 +42,7 @@ class NoticeForm(Form): """ - request: 'GazetteRequest' + request: GazetteRequest title = StringField( label=_('Title (maximum 60 characters)'), @@ -196,7 +198,7 @@ def on_request(self) -> None: if not self.request.is_private(self.model): self.delete_field('print_only') - def update_model(self, model: 'GazetteNotice') -> None: + def update_model(self, model: GazetteNotice) -> None: assert self.title.data is not None model.title = self.title.data model.organization_id = self.organization.data @@ -215,7 +217,7 @@ def update_model(self, model: 'GazetteNotice') -> None: model.user.phone_number = self.phone_number.formatted_data model.apply_meta(self.request.session) - def apply_model(self, model: 'GazetteNotice') -> None: + def apply_model(self, model: GazetteNotice) -> None: self.title.data = model.title self.organization.data = model.organization_id self.category.data = model.category_id @@ -292,7 +294,7 @@ def disable_issues(self) -> None: self.issues.validators = [] self.issues.render_kw['disabled'] = True - def update_model(self, model: 'GazetteNotice') -> None: + def update_model(self, model: GazetteNotice) -> None: assert self.title.data is not None model.title = self.title.data model.organization_id = self.organization.data @@ -311,6 +313,6 @@ def update_model(self, model: 'GazetteNotice') -> None: model.user.phone_number = self.phone_number.formatted_data model.apply_meta(self.request.session) - def apply_model(self, model: 'GazetteNotice') -> None: + def apply_model(self, model: GazetteNotice) -> None: super().apply_model(model) self.note.data = model.note diff --git a/src/onegov/gazette/forms/organization.py b/src/onegov/gazette/forms/organization.py index 43ec974553..cb9e051206 100644 --- a/src/onegov/gazette/forms/organization.py +++ b/src/onegov/gazette/forms/organization.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.form.fields import ChosenSelectField from onegov.form.validators import UniqueColumnValue diff --git a/src/onegov/gazette/forms/user.py b/src/onegov/gazette/forms/user.py index f9b54b21cc..7d4b9b06f4 100644 --- a/src/onegov/gazette/forms/user.py +++ b/src/onegov/gazette/forms/user.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.form.fields import ChosenSelectField, ChosenSelectMultipleField from onegov.form.fields import PhoneNumberField diff --git a/src/onegov/gazette/i18n.py b/src/onegov/gazette/i18n.py index c1ff5a4e7c..2f42263647 100644 --- a/src/onegov/gazette/i18n.py +++ b/src/onegov/gazette/i18n.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.i18n.translation_string import TranslationStringFactory _ = TranslationStringFactory('onegov.gazette') diff --git a/src/onegov/gazette/layout.py b/src/onegov/gazette/layout.py index b79519445b..a8cd38fe72 100644 --- a/src/onegov/gazette/layout.py +++ b/src/onegov/gazette/layout.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from markupsafe import Markup from onegov.core.layout import ChameleonLayout @@ -38,13 +40,13 @@ class Layout(ChameleonLayout): - request: 'GazetteRequest' + request: GazetteRequest date_with_weekday_format = 'EEEE dd.MM.yyyy' date_long_format = 'd. MMMM yyyy' datetime_with_weekday_format = 'EEEE dd.MM.yyyy HH:mm' - def __init__(self, model: Any, request: 'GazetteRequest') -> None: + def __init__(self, model: Any, request: GazetteRequest) -> None: super().__init__(model, request) self.request.include('frameworks') self.request.include('chosen') @@ -62,7 +64,7 @@ def principal(self) -> Principal: return self.request.app.principal @cached_property - def user(self) -> 'User | None': + def user(self) -> User | None: username = self.request.identity.userid if username: return UserCollection( @@ -187,7 +189,7 @@ def importation(self) -> bool: return True if self.request.app.principal.sogc_import else False @property - def menu(self) -> 'NestedMenu': + def menu(self) -> NestedMenu: result: NestedMenu = [] if self.request.is_private(self.model): @@ -322,7 +324,7 @@ def menu(self) -> 'NestedMenu': def current_issue(self) -> Issue | None: return IssueCollection(self.session).current_issue - def format_date(self, dt: 'datetime | date | None', format: str) -> str: + def format_date(self, dt: datetime | date | None, format: str) -> str: """ Returns a readable version of the given date while automatically converting to the principals timezone if the date is timezone aware. @@ -335,7 +337,7 @@ def format_issue( self, issue: Issue, date_format: str = 'date', - notice: 'GazetteNotice | None' = None + notice: GazetteNotice | None = None ) -> str: """ Returns the issues number and date and optionally the publication number of the given notice. """ @@ -372,7 +374,7 @@ class MailLayout(Layout): """ A special layout for creating HTML E-Mails. """ @cached_property - def base(self) -> 'PageTemplateFile': + def base(self) -> PageTemplateFile: return self.template_loader['mail_layout.pt'] @cached_property diff --git a/src/onegov/gazette/models/__init__.py b/src/onegov/gazette/models/__init__.py index 899ec81ae1..1ceb40dac5 100644 --- a/src/onegov/gazette/models/__init__.py +++ b/src/onegov/gazette/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.gazette.models.category import Category from onegov.gazette.models.issue import Issue from onegov.gazette.models.issue import IssueName diff --git a/src/onegov/gazette/models/category.py b/src/onegov/gazette/models/category.py index f1dad1a229..43bb26a23f 100644 --- a/src/onegov/gazette/models/category.py +++ b/src/onegov/gazette/models/category.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.abstract import AdjacencyList from onegov.core.orm.mixins import ContentMixin from onegov.core.orm.mixins import TimestampMixin @@ -29,19 +31,19 @@ class Category(AdjacencyList, ContentMixin, TimestampMixin): __tablename__ = 'gazette_categories' #: True, if this category is still in use. - active: 'Column[bool | None]' = Column(Boolean, nullable=True) + active: Column[bool | None] = Column(Boolean, nullable=True) if TYPE_CHECKING: # we need to override these attributes to get the correct base class - parent: relationship['Category | None'] - children: relationship[Sequence['Category']] + parent: relationship[Category | None] + children: relationship[Sequence[Category]] @property - def root(self) -> 'Category': ... + def root(self) -> Category: ... @property - def ancestors(self) -> Iterator['Category']: ... + def ancestors(self) -> Iterator[Category]: ... - def notices(self) -> 'Query[GazetteNotice]': + def notices(self) -> Query[GazetteNotice]: """ Returns a query to get all notices related to this category. """ from onegov.gazette.models.notice import GazetteNotice # circular diff --git a/src/onegov/gazette/models/issue.py b/src/onegov/gazette/models/issue.py index 8ff23bc0ea..f64ac5aba7 100644 --- a/src/onegov/gazette/models/issue.py +++ b/src/onegov/gazette/models/issue.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.crypto import random_token from onegov.core.orm import Base from onegov.core.orm.mixins import TimestampMixin @@ -43,7 +45,7 @@ def __repr__(self) -> str: return f'{self.year}-{self.number}' @classmethod - def from_string(cls, value: str) -> 'Self': + def from_string(cls, value: str) -> Self: year, number = value.split('-', maxsplit=1) return cls(int(year), int(number)) @@ -58,21 +60,21 @@ class Issue(Base, TimestampMixin, AssociatedFiles): __tablename__ = 'gazette_issues' #: the id of the db record (only relevant internally) - id: 'Column[int]' = Column(Integer, primary_key=True) + id: Column[int] = Column(Integer, primary_key=True) #: The name of the issue. - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: The number of the issue. - number: 'Column[int | None]' = Column(Integer, nullable=True) + number: Column[int | None] = Column(Integer, nullable=True) # The issue date. # FIXME: This clearly is meant to not be nullable, the observer # only works if all dates are set - date: 'Column[date_t]' = Column(Date, nullable=True) # type:ignore + date: Column[date_t] = Column(Date, nullable=True) # type:ignore # The deadline of this issue. - deadline: 'Column[datetime | None]' = Column(UTCDateTime, nullable=True) + deadline: Column[datetime | None] = Column(UTCDateTime, nullable=True) @property def pdf(self) -> File | None: @@ -92,8 +94,8 @@ def pdf(self, value: bytes | IO[bytes]) -> None: def notices( self, - state: 'NoticeState | None' = None - ) -> 'Query[GazetteNotice]': + state: NoticeState | None = None + ) -> Query[GazetteNotice]: """ Returns a query to get all notices related to this issue. """ from onegov.gazette.models.notice import GazetteNotice # circular @@ -135,7 +137,7 @@ def first_publication_number(self) -> int: def publication_numbers( self, - state: 'NoticeState | None' = None + state: NoticeState | None = None ) -> dict[int, str | None]: """ Returns a dictionary containing all publication numbers (by notice) of this issue. @@ -158,7 +160,7 @@ def in_use(self) -> bool: return session.query(self.notices().exists()).scalar() @observes('date') - def date_observer(self, date_: 'date_t') -> None: + def date_observer(self, date_: date_t) -> None: """ Changes the issue date of the notices when updating the date of the issue. @@ -183,7 +185,7 @@ def date_observer(self, date_: 'date_t') -> None: if (date := issues.get(issue, None)) ) - def publish(self, request: 'GazetteRequest') -> None: + def publish(self, request: GazetteRequest) -> None: """ Publishes the issue. This ensures that every accepted notice of this issue is published. It diff --git a/src/onegov/gazette/models/notice.py b/src/onegov/gazette/models/notice.py index bcb4cd349a..e75259c7ed 100644 --- a/src/onegov/gazette/models/notice.py +++ b/src/onegov/gazette/models/notice.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from datetime import date from onegov.chat import Message @@ -120,7 +122,7 @@ def group_name(self) -> str | None: def _group_observer( self, - group: 'UserGroup | None', + group: UserGroup | None, name: str | None ) -> None: """ Upates the last known name of the group. @@ -140,7 +142,7 @@ class GazetteNoticeFile(File): if TYPE_CHECKING: # we manually add the backref AssociatedFiles creates - linked_official_notices: relationship[list['GazetteNotice']] + linked_official_notices: relationship[list[GazetteNotice]] class GazetteNotice( @@ -178,7 +180,7 @@ class GazetteNotice( billing_address: dict_property[str | None] billing_address = content_property('billing_address') - changes: 'relationship[AppenderQuery[GazetteNoticeChange]]' = relationship( + changes: relationship[AppenderQuery[GazetteNoticeChange]] = relationship( 'GazetteNoticeChange', back_populates='notice', primaryjoin=( @@ -202,14 +204,14 @@ def user_observer( @observes('group', 'group.name') def group_observer( self, - group: 'UserGroup | None', + group: UserGroup | None, name: str | None ) -> None: self._group_observer(group, name) def add_change( self, - request: 'GazetteRequest', + request: GazetteRequest, event: str, text: str | None = None ) -> None: @@ -233,7 +235,7 @@ def add_change( ) ) - def submit(self, request: 'GazetteRequest') -> None: # type:ignore + def submit(self, request: GazetteRequest) -> None: # type:ignore """ Submit a drafted notice. This automatically adds en entry to the changelog. @@ -245,7 +247,7 @@ def submit(self, request: 'GazetteRequest') -> None: # type:ignore def reject( # type:ignore[override] self, - request: 'GazetteRequest', + request: GazetteRequest, comment: str ) -> None: """ Reject a submitted notice. @@ -257,7 +259,7 @@ def reject( # type:ignore[override] super().reject() self.add_change(request, _('rejected'), comment) - def accept(self, request: 'GazetteRequest') -> None: # type:ignore + def accept(self, request: GazetteRequest) -> None: # type:ignore """ Accept a submitted notice. This automatically adds en entry to the changelog. @@ -267,7 +269,7 @@ def accept(self, request: 'GazetteRequest') -> None: # type:ignore super().accept() self.add_change(request, _('accepted')) - def publish(self, request: 'GazetteRequest') -> None: # type:ignore + def publish(self, request: GazetteRequest) -> None: # type:ignore """ Publish an accepted notice. This automatically adds en entry to the changelog. @@ -300,7 +302,7 @@ def issues(self) -> dict[str, str | None]: # FIXME: asymmetric properties don't work @issues.setter - def issues(self, value: 'dict[str, str | None] | Iterable[str]') -> None: + def issues(self, value: dict[str, str | None] | Iterable[str]) -> None: if isinstance(value, dict): self._issues = value else: @@ -402,7 +404,7 @@ def invalid_organization(self) -> bool: row = query.filter(Organization.name == self.organization_id).first() return (not row[0]) if row else True - def apply_meta(self, session: 'Session') -> None: + def apply_meta(self, session: Session) -> None: """ Updates the category, organization and issue date from the meta values. @@ -436,7 +438,7 @@ class GazetteNoticeChange(Message, CachedUserNameMixin): __mapper_args__ = {'polymorphic_identity': 'gazette_notice'} #: the user which made this change - user: 'relationship[User | None]' = relationship( + user: relationship[User | None] = relationship( User, primaryjoin=( 'foreign(GazetteNoticeChange.owner) == cast(User.id, TEXT)' @@ -454,7 +456,7 @@ def user_observer( self._user_observer(user, realname, username) #: the notice which this change belongs to - notice: 'relationship[GazetteNotice]' = relationship( + notice: relationship[GazetteNotice] = relationship( GazetteNotice, primaryjoin=( 'foreign(GazetteNoticeChange.channel_id)' diff --git a/src/onegov/gazette/models/organization.py b/src/onegov/gazette/models/organization.py index 29707fb108..1905dcfe4a 100644 --- a/src/onegov/gazette/models/organization.py +++ b/src/onegov/gazette/models/organization.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.abstract import AdjacencyList from onegov.core.orm.abstract import MoveDirection from onegov.core.orm.mixins import ContentMixin @@ -34,21 +36,21 @@ class Organization(AdjacencyList, ContentMixin, TimestampMixin): __tablename__ = 'gazette_organizations' #: True, if this organization is still in use. - active: 'Column[bool | None]' = Column(Boolean, nullable=True) + active: Column[bool | None] = Column(Boolean, nullable=True) external_name: dict_property[str | None] = meta_property('external_name') if TYPE_CHECKING: # we need to override these attributes to get the correct base class - parent: relationship['Organization | None'] - children: relationship[Sequence['Organization']] + parent: relationship[Organization | None] + children: relationship[Sequence[Organization]] @property - def root(self) -> 'Organization': ... + def root(self) -> Organization: ... @property - def ancestors(self) -> Iterator['Organization']: ... + def ancestors(self) -> Iterator[Organization]: ... - def notices(self) -> 'Query[GazetteNotice]': + def notices(self) -> Query[GazetteNotice]: """ Returns a query to get all notices related to this category. """ from onegov.gazette.models.notice import GazetteNotice # circular @@ -87,7 +89,7 @@ class OrganizationMove: def __init__( self, - session: 'Session', + session: Session, subject_id: int, target_id: int, direction: MoveDirection diff --git a/src/onegov/gazette/models/principal.py b/src/onegov/gazette/models/principal.py index 781bdcfff2..4041ae4b3c 100644 --- a/src/onegov/gazette/models/principal.py +++ b/src/onegov/gazette/models/principal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from yaml import safe_load @@ -60,5 +62,5 @@ def __init__( self.sogc_import['canton'] = canton.upper() @classmethod - def from_yaml(cls, yaml_source: str) -> 'Self': + def from_yaml(cls, yaml_source: str) -> Self: return cls(**safe_load(yaml_source)) diff --git a/src/onegov/gazette/observer.py b/src/onegov/gazette/observer.py index a5e5bdaecf..7d7f4bd1f2 100644 --- a/src/onegov/gazette/observer.py +++ b/src/onegov/gazette/observer.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import observes as base_observes @@ -8,5 +10,5 @@ _F = TypeVar('_F', bound=Callable[..., Any]) -def observes(*paths: str) -> 'Callable[[_F], _F]': +def observes(*paths: str) -> Callable[[_F], _F]: return base_observes(*paths, scope='onegov.gazette.app.GazetteApp') diff --git a/src/onegov/gazette/path.py b/src/onegov/gazette/path.py index ec3266a64a..fe35e25c17 100644 --- a/src/onegov/gazette/path.py +++ b/src/onegov/gazette/path.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.converters import extended_date_converter from onegov.core.converters import move_direction_converter from onegov.core.converters import uuid_converter @@ -33,7 +35,7 @@ @GazetteApp.path(model=Auth, path='/auth') -def get_auth(request: 'GazetteRequest', to: str = '/') -> Auth: +def get_auth(request: GazetteRequest, to: str = '/') -> Auth: return Auth.from_request(request, to) @@ -102,7 +104,7 @@ def get_organization(app: GazetteApp, id: int) -> Organization | None: def get_page_move( app: GazetteApp, subject_id: int, - direction: 'MoveDirection', + direction: MoveDirection, target_id: int ) -> OrganizationMove: return OrganizationMove(app.session(), subject_id, target_id, direction) @@ -120,7 +122,7 @@ def get_issue(app: GazetteApp, name: str) -> Issue | None: @GazetteApp.path(model=IssuePdfFile, path='/pdf/{name}') def get_issue_pdf( - request: 'GazetteRequest', + request: GazetteRequest, app: GazetteApp, name: str ) -> IssuePdfFile | None: @@ -150,11 +152,11 @@ def get_notices( term: str | None = None, order: str | None = None, direction: str | None = None, - from_date: 'date | None' = None, - to_date: 'date | None' = None, + from_date: date | None = None, + to_date: date | None = None, categories: list[str] | None = None, organizations: list[str] | None = None, - source: 'UUID | None' = None, + source: UUID | None = None, own: bool | None = None ) -> GazetteNoticeCollection: diff --git a/src/onegov/gazette/pdf.py b/src/onegov/gazette/pdf.py index 943db8d443..89731286d1 100644 --- a/src/onegov/gazette/pdf.py +++ b/src/onegov/gazette/pdf.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from copy import deepcopy from io import BytesIO from onegov.gazette import _ @@ -65,7 +67,7 @@ def adjust_style(self, font_size: int = 10) -> None: self.style.index.firstLineIndent = -2 * self.style.index.fontSize self.style.index.leftIndent = 2 * self.style.index.fontSize - def category_index(self, notices: 'GazetteNoticeCollection') -> None: + def category_index(self, notices: GazetteNoticeCollection) -> None: """ Adds a category index. """ last_title: str | None = None @@ -99,7 +101,7 @@ def category_index(self, notices: 'GazetteNoticeCollection') -> None: style=self.style.index ) - def organization_index(self, notices: 'GazetteNoticeCollection') -> None: + def organization_index(self, notices: GazetteNoticeCollection) -> None: """ Adds an organization index. """ last_title: str | None = None @@ -140,8 +142,8 @@ def organization_index(self, notices: 'GazetteNoticeCollection') -> None: @classmethod def from_notices( cls, - notices: 'GazetteNoticeCollection', - request: 'GazetteRequest' + notices: GazetteNoticeCollection, + request: GazetteRequest ) -> BytesIO: """ Create an index PDF from a collection of notices. """ @@ -226,7 +228,7 @@ def notice( def from_notice( cls, notice: GazetteNotice, - request: 'GazetteRequest' + request: GazetteRequest ) -> BytesIO: """ Create a PDF from a single notice. """ @@ -251,8 +253,8 @@ def from_notice( @classmethod def from_notices( cls, - notices: 'GazetteNoticeCollection', - request: 'GazetteRequest' + notices: GazetteNoticeCollection, + request: GazetteRequest ) -> BytesIO: """ Create a PDF from a collection of notices. """ @@ -320,7 +322,7 @@ def notice( def excluded_notices_note( self, number: int, - request: 'GazetteRequest' + request: GazetteRequest ) -> None: """ Adds a paragraph with the number of excluded (print only) notices. @@ -344,7 +346,7 @@ def excluded_notices_note( def unfold_data( self, - session: 'Session', + session: Session, layout: Layout, issue: str, data: list[dict[str, Any]], @@ -383,11 +385,11 @@ def unfold_data( @staticmethod def query_notices( - session: 'Session', + session: Session, issue: str, organization: str, category: str - ) -> list['UUID']: + ) -> list[UUID]: """ Queries all notices with the given values, ordered by publication number. @@ -411,8 +413,8 @@ def query_notices( @classmethod def query_used_categories( cls, - session: 'Session', - issue: 'Issue' + session: Session, + issue: Issue ) -> set[str]: query = session.query(GazetteNotice._categories.keys()) # type:ignore @@ -425,8 +427,8 @@ def query_used_categories( @classmethod def query_used_organizations( cls, - session: 'Session', - issue: 'Issue' + session: Session, + issue: Issue ) -> set[str]: query = session.query( @@ -441,8 +443,8 @@ def query_used_organizations( @classmethod def query_excluded_notices_count( cls, - session: 'Session', - issue: 'Issue' + session: Session, + issue: Issue ) -> int: query = session.query(func.count(GazetteNotice.id)) query = query.filter( @@ -455,8 +457,8 @@ def query_excluded_notices_count( @classmethod def from_issue( cls, - issue: 'Issue', - request: 'GazetteRequest', + issue: Issue, + request: GazetteRequest, first_publication_number: int | None, links: dict[str, str] | None = None ) -> BytesIO: @@ -588,7 +590,7 @@ def notice( def excluded_notices_note( self, number: int, - request: 'GazetteRequest' + request: GazetteRequest ) -> None: """ Adds a paragraph with the number of excluded (print only) notices. @@ -610,11 +612,11 @@ def excluded_notices_note( @staticmethod def query_notices( - session: 'Session', + session: Session, issue: str, organization: str, category: str - ) -> list['UUID']: + ) -> list[UUID]: """ Queries all notices with the given values, ordered by publication number. @@ -639,8 +641,8 @@ def query_notices( @classmethod def query_used_categories( cls, - session: 'Session', - issue: 'Issue' + session: Session, + issue: Issue ) -> set[str]: query = session.query(GazetteNotice._categories.keys()) # type:ignore @@ -654,8 +656,8 @@ def query_used_categories( @classmethod def query_used_organizations( cls, - session: 'Session', - issue: 'Issue' + session: Session, + issue: Issue ) -> set[str]: query = session.query( @@ -671,8 +673,8 @@ def query_used_organizations( @classmethod def from_issue( # type:ignore[override] cls, - issue: 'Issue', - request: 'GazetteRequest' + issue: Issue, + request: GazetteRequest ) -> BytesIO: """ Generate a PDF for one issue. """ diff --git a/src/onegov/gazette/request.py b/src/onegov/gazette/request.py index 6f939fed42..5da3ce7ea7 100644 --- a/src/onegov/gazette/request.py +++ b/src/onegov/gazette/request.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.request import CoreRequest diff --git a/src/onegov/gazette/theme/__init__.py b/src/onegov/gazette/theme/__init__.py index d57de95645..8e9e23f544 100644 --- a/src/onegov/gazette/theme/__init__.py +++ b/src/onegov/gazette/theme/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.gazette.theme.gazette_theme import GazetteTheme __all__ = ('GazetteTheme',) diff --git a/src/onegov/gazette/theme/gazette_theme.py b/src/onegov/gazette/theme/gazette_theme.py index f9fa523c2f..4f4437c2b9 100644 --- a/src/onegov/gazette/theme/gazette_theme.py +++ b/src/onegov/gazette/theme/gazette_theme.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.foundation import BaseTheme from onegov.core.utils import module_path @@ -20,7 +22,7 @@ def default_options(self) -> dict[str, str]: # Leave this empty, see below return {} - def compile(self, options: 'Mapping[str, Any] | None' = None) -> str: + def compile(self, options: Mapping[str, Any] | None = None) -> str: # FIXME: We should just gracefully fallback to a default primary-color # since that is the only attribute from options we care about assert options is not None diff --git a/src/onegov/gazette/translations.py b/src/onegov/gazette/translations.py index 0cba649990..a277972f9f 100644 --- a/src/onegov/gazette/translations.py +++ b/src/onegov/gazette/translations.py @@ -2,6 +2,7 @@ exist in external packages which provide no translations. """ +from __future__ import annotations from onegov.gazette import _ diff --git a/src/onegov/gazette/upgrade.py b/src/onegov/gazette/upgrade.py index 682d9fd3e1..0ddeea1c15 100644 --- a/src/onegov/gazette/upgrade.py +++ b/src/onegov/gazette/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + from onegov.core.orm.types import JSON from onegov.core.upgrade import upgrade_task from onegov.core.upgrade import UpgradeContext diff --git a/src/onegov/gazette/utils/__init__.py b/src/onegov/gazette/utils/__init__.py index 0e81f723ff..879a0e82a1 100644 --- a/src/onegov/gazette/utils/__init__.py +++ b/src/onegov/gazette/utils/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.gazette.utils.orm import bool_is from onegov.gazette.utils.sogc_importer import SogcImporter diff --git a/src/onegov/gazette/utils/orm.py b/src/onegov/gazette/utils/orm.py index 8900fefe56..cce9c1b3e3 100644 --- a/src/onegov/gazette/utils/orm.py +++ b/src/onegov/gazette/utils/orm.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from sqlalchemy import or_ from typing import TYPE_CHECKING @@ -9,9 +11,9 @@ # should just get rid of this utility, unless we sometimes actually # pass in a boolean value, rather than a literal def bool_is( - column: 'ColumnElement[bool | None]', + column: ColumnElement[bool | None], value: bool -) -> 'ColumnElement[bool]': +) -> ColumnElement[bool]: """ Returns a SqlAlchemyStatements checking for boolean values of JSON attibutes. Missing values are interpreted as False. """ diff --git a/src/onegov/gazette/utils/sogc_converter.py b/src/onegov/gazette/utils/sogc_converter.py index 4e66958d50..99b285530e 100644 --- a/src/onegov/gazette/utils/sogc_converter.py +++ b/src/onegov/gazette/utils/sogc_converter.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from dateutil.parser import parse from markupsafe import Markup from onegov.gazette.models import Issue @@ -30,7 +32,7 @@ class SogcConverter: """ The base class for all converters. """ - def __init__(self, root: '_Element') -> None: + def __init__(self, root: _Element) -> None: self.root = root # FIXME: This returning Literal[""] regardless of the conversion @@ -40,23 +42,23 @@ def __init__(self, root: '_Element') -> None: def get( self, path: str, - converter: 'Callable[[str], Markup] | None' = html_converter, - root: '_Element | None' = None + converter: Callable[[str], Markup] | None = html_converter, + root: _Element | None = None ) -> Markup | Literal['']: ... @overload def get( self, path: str, - converter: 'Callable[[str], _T]', - root: '_Element | None' = None - ) -> '_T | Literal[""]': ... + converter: Callable[[str], _T], + root: _Element | None = None + ) -> _T | Literal['']: ... def get( self, path: str, - converter: 'Callable[[str], Any] | None' = html_converter, - root: '_Element | None' = None + converter: Callable[[str], Any] | None = html_converter, + root: _Element | None = None ) -> Any: root = root if root is not None else self.root @@ -66,7 +68,7 @@ def get( result = converter(result) return result - def get_line(self, path: str, root: '_Element | None' = None) -> str: + def get_line(self, path: str, root: _Element | None = None) -> str: return self.get(path, converter=line_converter, root=root) @property @@ -78,14 +80,14 @@ def source(self) -> str: return self.get_line('meta/publicationNumber') @property - def publication_date(self) -> 'datetime | Literal[""]': + def publication_date(self) -> datetime | Literal['']: return self.get('meta/publicationDate', converter=parse) @property - def expiration_date(self) -> 'datetime | Literal[""]': + def expiration_date(self) -> datetime | Literal['']: return self.get('meta/expirationDate', converter=parse) - def issues(self, session: 'Session') -> list[str]: + def issues(self, session: Session) -> list[str]: query = session.query(Issue.name) query = query.filter(Issue.date >= self.publication_date) query = query.order_by(Issue.date) diff --git a/src/onegov/gazette/utils/sogc_importer.py b/src/onegov/gazette/utils/sogc_importer.py index 390cf5b1fd..14ddb7a007 100644 --- a/src/onegov/gazette/utils/sogc_importer.py +++ b/src/onegov/gazette/utils/sogc_importer.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from lxml import etree from onegov.chat import MessageCollection from onegov.gazette import _ @@ -31,7 +33,7 @@ class SogcImporter: | KK06 | KK07 | KK08 | KK09 | KK10 ]] - def __init__(self, session: 'Session', config: dict[str, str]): + def __init__(self, session: Session, config: dict[str, str]): self.session = session self.endpoint = config['endpoint'].rstrip('/') self.canton = config['canton'] diff --git a/src/onegov/gazette/validators.py b/src/onegov/gazette/validators.py index e6b836539c..1385c2f87a 100644 --- a/src/onegov/gazette/validators.py +++ b/src/onegov/gazette/validators.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from wtforms.validators import ValidationError from onegov.gazette import _ @@ -25,10 +27,10 @@ class UnusedColumnKeyValue: # FIXME: Technically this should be 'ColumnElement[Mapping[str, Any]]' # but I don't think ColumnElement is covariant (it might be in # SQLAlchemy 2.0, so we should try changing it when we upgrade) - def __init__(self, column: 'ColumnElement[Any]') -> None: + def __init__(self, column: ColumnElement[Any]) -> None: self.column = column - def __call__(self, form: 'Form', field: 'Field') -> None: + def __call__(self, form: Form, field: Field) -> None: if not hasattr(form, 'model'): return diff --git a/src/onegov/gazette/views/__init__.py b/src/onegov/gazette/views/__init__.py index cc99ce18e6..4120e401b3 100644 --- a/src/onegov/gazette/views/__init__.py +++ b/src/onegov/gazette/views/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.user import UserCollection @@ -8,7 +10,7 @@ from uuid import UUID -def get_user(request: 'GazetteRequest') -> 'User | None': +def get_user(request: GazetteRequest) -> User | None: username = request.identity.userid if username is None: return None @@ -18,8 +20,8 @@ def get_user(request: 'GazetteRequest') -> 'User | None': def get_user_and_group( - request: 'GazetteRequest' -) -> tuple[list['UUID'], list['UUID']]: + request: GazetteRequest +) -> tuple[list[UUID], list[UUID]]: user = get_user(request) return ( diff --git a/src/onegov/gazette/views/auth.py b/src/onegov/gazette/views/auth.py index fdc3f02408..140d478ec0 100644 --- a/src/onegov/gazette/views/auth.py +++ b/src/onegov/gazette/views/auth.py @@ -1,4 +1,5 @@ """ The authentication views. """ +from __future__ import annotations from morepath import redirect from onegov.core.security import Personal @@ -34,9 +35,9 @@ ) def handle_login( self: Auth, - request: 'GazetteRequest', + request: GazetteRequest, form: LoginForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Handles the login requests. """ layout = Layout(self, request) @@ -58,7 +59,7 @@ def handle_login( @GazetteApp.html(model=Auth, name='logout', permission=Personal) -def view_logout(self: Auth, request: 'GazetteRequest') -> 'Response': +def view_logout(self: Auth, request: GazetteRequest) -> Response: """ Handles the logout requests. """ return self.logout_to(request) @@ -70,9 +71,9 @@ def view_logout(self: Auth, request: 'GazetteRequest') -> 'Response': ) def handle_password_reset_request( self: Principal, - request: 'GazetteRequest', + request: GazetteRequest, form: RequestPasswordResetForm -) -> 'RenderData': +) -> RenderData: """ Handles the password reset requests. """ show_form = True @@ -135,9 +136,9 @@ def handle_password_reset_request( ) def handle_password_reset( self: Principal, - request: 'GazetteRequest', + request: GazetteRequest, form: PasswordResetForm -) -> 'RenderData | Response': +) -> RenderData | Response: layout = Layout(self, request) callout = None @@ -177,15 +178,15 @@ def handle_password_reset( ) def handle_totp_second_factor( self: Auth, - request: 'GazetteRequest', + request: GazetteRequest, form: TOTPForm -) -> 'RenderData | Response': +) -> RenderData | Response: if not request.app.totp_enabled: raise exc.HTTPNotFound() @request.after - def respond_with_no_index(response: 'Response') -> None: + def respond_with_no_index(response: Response) -> None: response.headers['X-Robots-Tag'] = 'noindex' users = UserCollection(request.session) diff --git a/src/onegov/gazette/views/categories.py b/src/onegov/gazette/views/categories.py index 7ee77429be..4e7d07b7f6 100644 --- a/src/onegov/gazette/views/categories.py +++ b/src/onegov/gazette/views/categories.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from io import BytesIO from morepath import redirect from morepath.request import Response @@ -27,8 +29,8 @@ ) def view_categories( self: CategoryCollection, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: """ View the list of categories. This view is only visible by an admin. @@ -54,9 +56,9 @@ def view_categories( ) def create_category( self: CategoryCollection, - request: 'GazetteRequest', + request: GazetteRequest, form: CategoryForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Create a new category. This view is only visible by an admin. @@ -92,9 +94,9 @@ def create_category( ) def edit_category( self: Category, - request: 'GazetteRequest', + request: GazetteRequest, form: CategoryForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Edit a category. This view is only visible by an admin. @@ -129,9 +131,9 @@ def edit_category( ) def delete_category( self: Category, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Delete a category. Only unused categorys may be deleted. @@ -180,7 +182,7 @@ def delete_category( ) def export_categories( self: CategoryCollection, - request: 'GazetteRequest' + request: GazetteRequest ) -> Response: """ Export all categories as XLSX. The exported file can be re-imported using the import-categories command line command. diff --git a/src/onegov/gazette/views/exceptions.py b/src/onegov/gazette/views/exceptions.py index 9a6b8441cf..04c6c3cad0 100644 --- a/src/onegov/gazette/views/exceptions.py +++ b/src/onegov/gazette/views/exceptions.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Public from onegov.gazette import _ from onegov.gazette import GazetteApp @@ -20,11 +22,11 @@ ) def handle_forbidden( self: HTTPForbidden, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: @request.after - def set_status_code(response: 'Response') -> None: + def set_status_code(response: Response) -> None: response.status_code = self.code # pass along 403 return { @@ -43,11 +45,11 @@ def set_status_code(response: 'Response') -> None: ) def handle_notfound( self: HTTPNotFound, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: @request.after - def set_status_code(response: 'Response') -> None: + def set_status_code(response: Response) -> None: response.status_code = self.code # pass along 404 return { diff --git a/src/onegov/gazette/views/groups.py b/src/onegov/gazette/views/groups.py index 2bc2ae8709..28bb45709e 100644 --- a/src/onegov/gazette/views/groups.py +++ b/src/onegov/gazette/views/groups.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.security import Private from onegov.gazette import _ @@ -23,8 +25,8 @@ ) def view_groups( self: UserGroupCollection[UserGroup], - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: """ View all the user groups. This view is only visible by an admin. @@ -49,9 +51,9 @@ def view_groups( ) def create_group( self: UserGroupCollection[UserGroup], - request: 'GazetteRequest', + request: GazetteRequest, form: UserGroupForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Create a new user group. This view is only visible by an admin. @@ -82,9 +84,9 @@ def create_group( ) def edit_group( self: UserGroup, - request: 'GazetteRequest', + request: GazetteRequest, form: UserGroupForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Edit a user group. This view is only visible by an admin. @@ -119,9 +121,9 @@ def edit_group( ) def delete_group( self: UserGroup, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Delete a user group. This view is only visible by an admin. diff --git a/src/onegov/gazette/views/issues.py b/src/onegov/gazette/views/issues.py index 9332aa20fc..8cf330e3b6 100644 --- a/src/onegov/gazette/views/issues.py +++ b/src/onegov/gazette/views/issues.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from io import BytesIO from morepath import redirect @@ -30,8 +32,8 @@ ) def view_issues( self: IssueCollection, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: """ View the list of issues. This view is only visible by a publisher. @@ -63,9 +65,9 @@ def view_issues( ) def create_issue( self: IssueCollection, - request: 'GazetteRequest', + request: GazetteRequest, form: IssueForm -) -> 'RenderData | BaseReponse': +) -> RenderData | BaseReponse: """ Create a new issue. This view is only visible by a publisher. @@ -98,9 +100,9 @@ def create_issue( ) def edit_issue( self: Issue, - request: 'GazetteRequest', + request: GazetteRequest, form: IssueForm -) -> 'RenderData | BaseReponse': +) -> RenderData | BaseReponse: """ Edit a issue. This view is only visible by a publisher. @@ -135,9 +137,9 @@ def edit_issue( ) def delete_issue( self: Issue, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | BaseReponse': +) -> RenderData | BaseReponse: """ Delete a issue. Only unused issues may be deleted. @@ -190,9 +192,9 @@ def delete_issue( ) def publish_issue( self: Issue, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | BaseReponse': +) -> RenderData | BaseReponse: """ Publish an issue. This moves all accepted notices related to this issue to the published @@ -270,7 +272,7 @@ def publish_issue( name='print-only-pdf', permission=Private ) -def print_only_pdf(self: Issue, request: 'GazetteRequest') -> Response: +def print_only_pdf(self: Issue, request: GazetteRequest) -> Response: """ Creates the PDF with all the print only notices of an issue. """ response = Response() @@ -288,7 +290,7 @@ def print_only_pdf(self: Issue, request: 'GazetteRequest') -> Response: name='export', permission=Private ) -def export_issue(self: IssueCollection, request: 'GazetteRequest') -> Response: +def export_issue(self: IssueCollection, request: GazetteRequest) -> Response: """ Export all issues as XLSX. The exported file can be re-imported using the import-issues command line command. diff --git a/src/onegov/gazette/views/notice.py b/src/onegov/gazette/views/notice.py index 901769f778..d09352f397 100644 --- a/src/onegov/gazette/views/notice.py +++ b/src/onegov/gazette/views/notice.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from morepath.request import Response from onegov.core.security import Personal @@ -30,8 +32,8 @@ ) def view_notice( self: GazetteNotice, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: """ View a notice. View the notice and its meta data. This is the main view for the notices @@ -132,8 +134,8 @@ def _action( ) def preview_notice( self: GazetteNotice, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: """ Preview the notice. """ layout = Layout(self, request) @@ -152,7 +154,7 @@ def preview_notice( ) def preview_notice_pdf( self: GazetteNotice, - request: 'GazetteRequest' + request: GazetteRequest ) -> Response: """ Preview the notice as PDF. """ @@ -182,9 +184,9 @@ def preview_notice_pdf( ) def edit_notice( self: GazetteNotice, - request: 'GazetteRequest', + request: GazetteRequest, form: NoticeForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Edit a notice. This view is used by the editors and publishers. Editors may only edit @@ -277,9 +279,9 @@ def edit_notice( ) def edit_notice_unrestricted( self: GazetteNotice, - request: 'GazetteRequest', + request: GazetteRequest, form: UnrestrictedNoticeForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Edit a notice without restrictions. This view is only usable by publishers. @@ -331,9 +333,9 @@ def edit_notice_unrestricted( ) def delete_notice( self: GazetteNotice, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Delete a notice. Editors may only delete their own drafted and rejected notices. diff --git a/src/onegov/gazette/views/notice_attachments.py b/src/onegov/gazette/views/notice_attachments.py index ba4dcb04bc..87c89b9f01 100644 --- a/src/onegov/gazette/views/notice_attachments.py +++ b/src/onegov/gazette/views/notice_attachments.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.crypto import random_token from onegov.core.security import Private @@ -26,8 +28,8 @@ ) def view_notice_attachments( self: GazetteNotice, - request: 'GazetteRequest' -) -> 'RenderData | Response': + request: GazetteRequest +) -> RenderData | Response: """ View all attachments to a single notice and allow to drop new attachments. @@ -61,8 +63,8 @@ def view_notice_attachments( ) def upload_attachment( self: GazetteNotice, - request: 'GazetteRequest' -) -> 'Response': + request: GazetteRequest +) -> Response: """ Upload an attachment and add it to the notice. Raises a HTTP 405 (Metho not Allowed) for non-admins if the notice has @@ -108,9 +110,9 @@ def upload_attachment( ) def delete_attachment( self: GazetteNoticeFile, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Delete a notice attachment. """ layout = Layout(self, request) diff --git a/src/onegov/gazette/views/notice_states.py b/src/onegov/gazette/views/notice_states.py index 8236998671..0e127415b4 100644 --- a/src/onegov/gazette/views/notice_states.py +++ b/src/onegov/gazette/views/notice_states.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.mail import Attachment from onegov.core.security import Personal @@ -22,7 +24,7 @@ def send_accepted_mail( - request: 'GazetteRequest', + request: GazetteRequest, notice: GazetteNotice ) -> None: """ Sends a mail to the publisher with the contents of the notice. @@ -35,7 +37,7 @@ def send_accepted_mail( def construct_subject( notice: GazetteNotice, - request: 'GazetteRequest' + request: GazetteRequest ) -> str: issues = notice.issue_objects @@ -92,9 +94,9 @@ def construct_subject( ) def submit_notice( self: GazetteNotice, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Submit a notice. This view is used by the editors to submit their drafts for the publishers @@ -163,9 +165,9 @@ def submit_notice( ) def accept_notice( self: GazetteNotice, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Accept a notice. This view is used by the publishers to accept a submitted notice. @@ -225,9 +227,9 @@ def accept_notice( ) def reject_notice( self: GazetteNotice, - request: 'GazetteRequest', + request: GazetteRequest, form: RejectForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Reject a notice. This view is used by the publishers to reject a submitted notice. diff --git a/src/onegov/gazette/views/notices.py b/src/onegov/gazette/views/notices.py index d85d5b81a5..a022c4c7f2 100644 --- a/src/onegov/gazette/views/notices.py +++ b/src/onegov/gazette/views/notices.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from io import BytesIO from morepath import redirect from morepath.request import Response @@ -38,9 +40,9 @@ ) def create_notice( self: GazetteNoticeCollection, - request: 'GazetteRequest', + request: GazetteRequest, form: NoticeForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Create a new notice. If a valid UID of a notice is given (via 'source' query parameter), its @@ -108,8 +110,8 @@ def create_notice( ) def view_notices( self: GazetteNoticeCollection, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: """ View the list of notices. This view is only visible by a publisher. This (in the state 'accepted') @@ -130,7 +132,7 @@ def view_notices( states.append('published') # https://kanton-zug.atlassian.net/browse/ZW-246 - def for_state(state: 'NoticeState') -> GazetteNoticeCollection: + def for_state(state: NoticeState) -> GazetteNoticeCollection: if state == 'accepted': return self.for_state(state).for_order('first_issue', 'desc') @@ -227,8 +229,8 @@ def for_state(state: 'NoticeState') -> GazetteNoticeCollection: ) def view_notices_statistics( self: GazetteNoticeCollection, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: """ View the list of notices. This view is only visible by a publisher. This (in the state 'accepted') @@ -277,7 +279,7 @@ def view_notices_statistics( ) def view_notices_statistics_xlsx( self: GazetteNoticeCollection, - request: 'GazetteRequest' + request: GazetteRequest ) -> Response: """ View the statistics as XLSX. """ @@ -321,7 +323,7 @@ def view_notices_statistics_xlsx( ) def view_notices_preview_pdf( self: GazetteNoticeCollection, - request: 'GazetteRequest' + request: GazetteRequest ) -> Response: """ Preview the notices as PDF. @@ -352,7 +354,7 @@ def view_notices_preview_pdf( ) def view_notices_index( self: GazetteNoticeCollection, - request: 'GazetteRequest' + request: GazetteRequest ) -> Response: """ Export the index to the notices as PDF. @@ -385,9 +387,9 @@ def view_notices_index( ) def view_notices_update( self: GazetteNoticeCollection, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Updates all notices (of this state): Applies the categories, issues and organization from the meta informations. This view is not used normally and only intended when changing category names in the principal definition, diff --git a/src/onegov/gazette/views/organizations.py b/src/onegov/gazette/views/organizations.py index 1852ee6f67..19806cbdb9 100644 --- a/src/onegov/gazette/views/organizations.py +++ b/src/onegov/gazette/views/organizations.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from io import BytesIO from morepath import redirect from morepath.request import Response @@ -28,8 +30,8 @@ ) def view_organizations( self: OrganizationCollection, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: """ View the list of organizations. This view is only visible by a publisher. @@ -56,8 +58,8 @@ def view_organizations( ) def view_organizations_order( self: OrganizationCollection, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: """ Reorder the list of organizations. This view is only visible by a publisher. @@ -80,7 +82,7 @@ def view_organizations_order( ) def move_organization( self: OrganizationMove, - request: 'GazetteRequest' + request: GazetteRequest ) -> None: request.assert_valid_csrf_token() @@ -96,9 +98,9 @@ def move_organization( ) def create_organization( self: OrganizationCollection, - request: 'GazetteRequest', + request: GazetteRequest, form: OrganizationForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Create a new organization. This view is only visible by a publisher. @@ -136,9 +138,9 @@ def create_organization( ) def edit_organization( self: Organization, - request: 'GazetteRequest', + request: GazetteRequest, form: OrganizationForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Edit a organization. This view is only visible by a publisher. @@ -173,9 +175,9 @@ def edit_organization( ) def delete_organization( self: Organization, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Delete a organization. Only unused organizations may be deleted. @@ -227,7 +229,7 @@ def delete_organization( ) def export_organizations( self: OrganizationCollection, - request: 'GazetteRequest' + request: GazetteRequest ) -> Response: """ Export all organizations as XLSX. The exported file can be re-imported using the import-organizations command line command. diff --git a/src/onegov/gazette/views/principal.py b/src/onegov/gazette/views/principal.py index 0b96a91365..a1295b86fc 100644 --- a/src/onegov/gazette/views/principal.py +++ b/src/onegov/gazette/views/principal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import timedelta from morepath import redirect from onegov.core.security import Personal @@ -23,7 +25,7 @@ model=Principal, permission=Public ) -def view_principal(self: Principal, request: 'GazetteRequest') -> 'Response': +def view_principal(self: Principal, request: GazetteRequest) -> Response: """ The homepage. Redirects to the default management views according to the logged in role. @@ -52,7 +54,7 @@ def view_principal(self: Principal, request: 'GazetteRequest') -> 'Response': name='archive', template='archive.pt', ) -def view_archive(self: Principal, request: 'GazetteRequest') -> 'RenderData': +def view_archive(self: Principal, request: GazetteRequest) -> RenderData: """ The archive. Shows all the weekly PDFs by year. @@ -72,7 +74,7 @@ def view_archive(self: Principal, request: 'GazetteRequest') -> 'RenderData': name='dashboard', template='dashboard.pt', ) -def view_dashboard(self: Principal, request: 'GazetteRequest') -> 'RenderData': +def view_dashboard(self: Principal, request: GazetteRequest) -> RenderData: """ The dashboard view (for editors). Shows the drafted, submitted and rejected notices, shows warnings and diff --git a/src/onegov/gazette/views/users.py b/src/onegov/gazette/views/users.py index d733d8e352..19eeae1411 100644 --- a/src/onegov/gazette/views/users.py +++ b/src/onegov/gazette/views/users.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from io import BytesIO from morepath import redirect from morepath.request import Response @@ -35,8 +37,8 @@ ) def view_users( self: UserCollection, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: """ View the users. Publishers can see editors, admins can see editors and publishers. Admins @@ -80,9 +82,9 @@ def view_users( ) def create_user( self: UserCollection, - request: 'GazetteRequest', + request: GazetteRequest, form: UserForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Create a new publisher or editor. This view is visible for admins and publishers. @@ -143,9 +145,9 @@ def create_user( ) def edit_user( self: User, - request: 'GazetteRequest', + request: GazetteRequest, form: UserForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Edit the role, name and email of a user. Publishers may only edit members. Admins can not be edited. @@ -184,9 +186,9 @@ def edit_user( ) def delete_user( self: User, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Delete a user. Publishers may only edit members. Admins can not be deleted. @@ -239,8 +241,8 @@ def delete_user( ) def view_user_sessions( self: UserCollection, - request: 'GazetteRequest' -) -> 'RenderData': + request: GazetteRequest +) -> RenderData: """ View all open browser sessions. This view is only visible by an admin. @@ -264,9 +266,9 @@ def view_user_sessions( ) def clear_user_sessions( self: User, - request: 'GazetteRequest', + request: GazetteRequest, form: EmptyForm -) -> 'RenderData | BaseResponse': +) -> RenderData | BaseResponse: """ Closes all open browser sessions. This view is only visible by an admin. @@ -303,9 +305,9 @@ def clear_user_sessions( ) def export_users( self: UserCollection, - request: 'GazetteRequest', + request: GazetteRequest, form: ExportUsersForm -) -> 'RenderData | Response': +) -> RenderData | Response: """ Export all users as XLSX. The exported file can be re-imported using the import-editors command line command. diff --git a/src/onegov/gever/encrypt.py b/src/onegov/gever/encrypt.py index ecf9bf6b69..b71d1b46c6 100644 --- a/src/onegov/gever/encrypt.py +++ b/src/onegov/gever/encrypt.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from cryptography.fernet import Fernet diff --git a/src/onegov/gever/gever_client.py b/src/onegov/gever/gever_client.py index e8aefdd8e3..ee44caef4f 100644 --- a/src/onegov/gever/gever_client.py +++ b/src/onegov/gever/gever_client.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import requests from base64 import b64encode diff --git a/src/onegov/gis/__init__.py b/src/onegov/gis/__init__.py index 0a70d692ff..0b88fd8301 100644 --- a/src/onegov/gis/__init__.py +++ b/src/onegov/gis/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.gis') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/gis/forms/__init__.py b/src/onegov/gis/forms/__init__.py index d24e8c12da..9d644cd2de 100644 --- a/src/onegov/gis/forms/__init__.py +++ b/src/onegov/gis/forms/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.gis.forms.fields import CoordinatesField from onegov.gis.forms.widgets import CoordinatesWidget diff --git a/src/onegov/gis/forms/fields.py b/src/onegov/gis/forms/fields.py index b7d5e5b1c1..9a47471b6d 100644 --- a/src/onegov/gis/forms/fields.py +++ b/src/onegov/gis/forms/fields.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from base64 import b64decode, b64encode from markupsafe import Markup from onegov.core.custom import json @@ -43,29 +45,29 @@ class CoordinatesField(StringField): """ - data: 'AnyCoordinates' # type:ignore[assignment] - widget: '_Widget[Self]' = CoordinatesWidget() # type:ignore[assignment] + data: AnyCoordinates # type:ignore[assignment] + widget: _Widget[Self] = CoordinatesWidget() # type:ignore[assignment] def __init__( self, label: str | None = None, - validators: 'Validators[FormT, Self] | None' = None, - filters: 'Sequence[_Filter]' = (), + validators: Validators[FormT, Self] | None = None, + filters: Sequence[_Filter] = (), description: str = '', id: str | None = None, - default: 'AnyCoordinates | Callable[[], AnyCoordinates] | None' = None, - widget: '_Widget[Self] | None' = None, + default: AnyCoordinates | Callable[[], AnyCoordinates] | None = None, + widget: _Widget[Self] | None = None, render_kw: dict[str, Any] | None = None, name: str | None = None, - _form: 'BaseForm | None' = None, + _form: BaseForm | None = None, _prefix: str = '', - _translations: '_SupportsGettextAndNgettext | None' = None, - _meta: 'DefaultMeta | None' = None, + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, # onegov specific kwargs that get popped off *, fieldset: str | None = None, - depends_on: 'Sequence[Any] | None' = None, - pricing: 'PricingRules | None' = None, + depends_on: Sequence[Any] | None = None, + pricing: PricingRules | None = None, ): super().__init__( label=label, @@ -102,7 +104,7 @@ def process_data(self, value: object) -> None: def populate_obj(self, obj: object, name: str) -> None: setattr(obj, name, self.data) - def process_formdata(self, valuelist: list['RawFormValue']) -> None: + def process_formdata(self, valuelist: list[RawFormValue]) -> None: if valuelist and valuelist[0]: assert isinstance(valuelist[0], str) text_b = b64decode(valuelist[0]) diff --git a/src/onegov/gis/forms/widgets.py b/src/onegov/gis/forms/widgets.py index 3a05a22962..74ea7f1eaf 100644 --- a/src/onegov/gis/forms/widgets.py +++ b/src/onegov/gis/forms/widgets.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from wtforms.widgets import TextInput @@ -18,9 +20,9 @@ class CoordinatesWidget(TextInput): def __call__( self, - field: 'CoordinatesField', # type:ignore[override] + field: CoordinatesField, # type:ignore[override] **kwargs: Any - ) -> 'Markup': + ) -> Markup: kwargs['class_'] = (kwargs.get('class_', '') + ' coordinates').strip() return super().__call__(field, **kwargs) diff --git a/src/onegov/gis/integration.py b/src/onegov/gis/integration.py index 2ead1a770e..c4742148a4 100644 --- a/src/onegov/gis/integration.py +++ b/src/onegov/gis/integration.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from more.webassets import WebassetsApp @@ -56,7 +58,7 @@ def get_css_path() -> str: @MapboxApp.webasset('leaflet', filters={'css': ['datauri', 'custom-rcssmin']}) -def get_leaflet_asset() -> 'Iterator[str]': +def get_leaflet_asset() -> Iterator[str]: yield 'leaflet.css' yield 'leaflet-easybutton.css' yield 'leaflet-control-geocoder.css' @@ -71,53 +73,53 @@ def get_leaflet_asset() -> 'Iterator[str]': @MapboxApp.webasset('proj4js') -def get_proj4js_asset() -> 'Iterator[str]': +def get_proj4js_asset() -> Iterator[str]: yield 'proj4js.js' yield 'proj4js-leaflet.js' @MapboxApp.webasset('geo-mapbox') -def get_geo_mapbox() -> 'Iterator[str]': +def get_geo_mapbox() -> Iterator[str]: yield 'leaflet' @MapboxApp.webasset('geo-vermessungsamt-winterthur') -def get_geo_vermessungsamt_winterthur() -> 'Iterator[str]': +def get_geo_vermessungsamt_winterthur() -> Iterator[str]: yield 'leaflet' yield 'proj4js' yield 'geo-vermessungsamt-winterthur.js' @MapboxApp.webasset('geo-zugmap-basisplan') -def get_geo_zugmap_basisplan() -> 'Iterator[str]': +def get_geo_zugmap_basisplan() -> Iterator[str]: yield 'leaflet' yield 'proj4js' yield 'geo-zugmap.js' @MapboxApp.webasset('geo-zugmap-orthofoto') -def get_geo_zugmap_orthofoto() -> 'Iterator[str]': +def get_geo_zugmap_orthofoto() -> Iterator[str]: yield 'leaflet' yield 'proj4js' yield 'geo-zugmap-orthofoto.js' @MapboxApp.webasset('geo-bs') -def get_geo_bs() -> 'Iterator[str]': +def get_geo_bs() -> Iterator[str]: yield 'leaflet' yield 'proj4js' yield 'geo-bs.js' @MapboxApp.webasset('geo-admin') -def get_geo_admin() -> 'Iterator[str]': +def get_geo_admin() -> Iterator[str]: yield 'leaflet' yield 'proj4js' yield 'geo-admin.js' @MapboxApp.webasset('geo-admin-aerial') -def get_geo_admin_aerial() -> 'Iterator[str]': +def get_geo_admin_aerial() -> Iterator[str]: yield 'leaflet' yield 'proj4js' yield 'geo-admin-aerial.js' @@ -126,13 +128,13 @@ def get_geo_admin_aerial() -> 'Iterator[str]': @MapboxApp.tween_factory() def inject_mapbox_api_token_tween_factory( app: MapboxApp, - handler: 'Callable[[CoreRequest], Response]' -) -> 'Callable[[CoreRequest], Response]': + handler: Callable[[CoreRequest], Response] +) -> Callable[[CoreRequest], Response]: replacement = ' 'Response': + def inject_mapbox_api_token_tween(request: CoreRequest) -> Response: response = handler(request) diff --git a/src/onegov/gis/models/__init__.py b/src/onegov/gis/models/__init__.py index be5a98bfea..432959e77f 100644 --- a/src/onegov/gis/models/__init__.py +++ b/src/onegov/gis/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.gis.models.coordinates import Coordinates, CoordinatesMixin __all__ = ('Coordinates', 'CoordinatesMixin') diff --git a/src/onegov/gis/models/coordinates.py b/src/onegov/gis/models/coordinates.py index 1eb8ec2bed..ff982c54f9 100644 --- a/src/onegov/gis/models/coordinates.py +++ b/src/onegov/gis/models/coordinates.py @@ -1,11 +1,15 @@ +from __future__ import annotations + from onegov.core.custom import json -from typing import overload, Any, Literal, TYPE_CHECKING +from typing import overload, Any, Literal, Self, TYPE_CHECKING if TYPE_CHECKING: from sqlalchemy.schema import Column from typing import TypeAlias + AnyCoordinates: TypeAlias = 'RealCoordinates | NullCoordinates' + class Coordinates(json.Serializable, keys=('lon', 'lat', 'zoom')): """ Represents a pair of coordinates. @@ -29,7 +33,7 @@ def __new__( lat: float, lon: float, zoom: int | None = None, - ) -> 'RealCoordinates': ... + ) -> RealCoordinates: ... @overload def __new__( @@ -37,14 +41,14 @@ def __new__( lat: None = None, lon: None = None, zoom: None = None, - ) -> 'NullCoordinates': ... + ) -> NullCoordinates: ... def __new__( cls, lat: float | None = None, lon: float | None = None, zoom: int | None = None, - ) -> 'Coordinates': + ) -> Self: raise NotImplementedError() else: @@ -94,8 +98,6 @@ class RealCoordinates(Coordinates, keys=('lon', 'lat', 'zoom')): def __bool__(self) -> Literal[True]: return True - AnyCoordinates: TypeAlias = RealCoordinates | NullCoordinates - class CoordinatesMixin: """ Extends any class that has a content dictionary field with a single @@ -108,10 +110,10 @@ class CoordinatesMixin: content: Column[dict[str, Any]] @property - def coordinates(self) -> 'AnyCoordinates': + def coordinates(self) -> AnyCoordinates: return self.content.get('coordinates') or Coordinates() @coordinates.setter - def coordinates(self, value: 'AnyCoordinates') -> None: + def coordinates(self, value: AnyCoordinates) -> None: self.content = self.content or {} self.content['coordinates'] = value or {} diff --git a/src/onegov/gis/utils.py b/src/onegov/gis/utils.py index 49ce9508f0..36a9327412 100644 --- a/src/onegov/gis/utils.py +++ b/src/onegov/gis/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import requests from purl import URL @@ -155,27 +157,27 @@ def geocode( @overload def directions( self, - coordinates: 'Iterable[tuple[str | float, str | float]]', + coordinates: Iterable[tuple[str | float, str | float]], as_url: Literal[False] = False ) -> requests.Response: ... @overload def directions( self, - coordinates: 'Iterable[tuple[str | float, str | float]]', + coordinates: Iterable[tuple[str | float, str | float]], as_url: Literal[True] ) -> URL: ... @overload def directions( self, - coordinates: 'Iterable[tuple[str | float, str | float]]', + coordinates: Iterable[tuple[str | float, str | float]], as_url: bool ) -> requests.Response | URL: ... def directions( self, - coordinates: 'Iterable[tuple[str | float, str | float]]', + coordinates: Iterable[tuple[str | float, str | float]], as_url: bool = False ) -> requests.Response | URL: """ @@ -190,8 +192,8 @@ def directions( def outside_bbox( - coordinate: 'AnyCoordinates | None', - bbox: 'Collection[RealCoordinates] | None' + coordinate: AnyCoordinates | None, + bbox: Collection[RealCoordinates] | None ) -> bool: """Checks if the Coordinates instance is inside the bounding box defined by the most outward sitting points in an iterable of two+ Coordinates. diff --git a/src/onegov/intranet/__init__.py b/src/onegov/intranet/__init__.py index 90f378588b..44aca405c3 100644 --- a/src/onegov/intranet/__init__.py +++ b/src/onegov/intranet/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.intranet.app import IntranetApp __all__ = ('IntranetApp', ) diff --git a/src/onegov/intranet/app.py b/src/onegov/intranet/app.py index e0da7d9b36..cae9ee1c57 100644 --- a/src/onegov/intranet/app.py +++ b/src/onegov/intranet/app.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.town6 import TownApp from typing import Any from typing import TYPE_CHECKING @@ -29,7 +31,7 @@ def configure_organisation( @IntranetApp.template_variables() -def get_template_variables(request: 'TownRequest') -> 'RenderData': +def get_template_variables(request: TownRequest) -> RenderData: return { 'global_tools': tuple(get_global_tools(request)), 'hide_search_header': not request.is_logged_in diff --git a/src/onegov/intranet/custom.py b/src/onegov/intranet/custom.py index 529278f6cd..47fc88cf6b 100644 --- a/src/onegov/intranet/custom.py +++ b/src/onegov/intranet/custom.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.elements import Link from onegov.org.custom import logout_path from onegov.org.elements import LinkGroup @@ -22,8 +24,8 @@ def get_global_tools( - request: 'TranslatorAppRequest' -) -> 'Iterator[Link | LinkGroup]': + request: TranslatorAppRequest +) -> Iterator[Link | LinkGroup]: if request.is_logged_in: assert request.current_username is not None @@ -150,7 +152,7 @@ def get_global_tools( def get_top_navigation( - request: 'TranslatorAppRequest') -> 'Iterator[NavigationEntry]': + request: TranslatorAppRequest) -> Iterator[NavigationEntry]: # inject an activites link in front of all top navigation links if request.is_manager or request.is_member: @@ -179,7 +181,7 @@ def get_top_navigation( @TranslatorDirectoryApp.template_variables() -def get_template_variables(request: 'TranslatorAppRequest') -> 'RenderData': +def get_template_variables(request: TranslatorAppRequest) -> RenderData: return { 'global_tools': tuple(get_global_tools(request)), 'top_navigation': tuple(get_top_navigation(request)), diff --git a/src/onegov/intranet/security.py b/src/onegov/intranet/security.py index 4bccc10a3f..8c755dd004 100644 --- a/src/onegov/intranet/security.py +++ b/src/onegov/intranet/security.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.metadata import PublicMetadata from onegov.core.security import Public, Private, Personal, Secret from onegov.core.static import StaticFile @@ -13,7 +15,7 @@ @IntranetApp.setting_section(section='roles') -def get_roles_setting() -> dict[str, set[type['Intent']]]: +def get_roles_setting() -> dict[str, set[type[Intent]]]: """ Returns the default roles available to onegov.core applications. Applications building on onegov.core may add more roles and permissions, @@ -69,7 +71,7 @@ def get_roles_setting() -> dict[str, set[type['Intent']]]: ) def may_view_static_files_not_logged_in( app: IntranetApp, - identity: 'NoIdentity', + identity: NoIdentity, model: StaticFile, permission: type[Public] ) -> bool: @@ -88,7 +90,7 @@ def may_view_static_files_not_logged_in( ) def may_view_theme_files_not_logged_in( app: IntranetApp, - identity: 'NoIdentity', + identity: NoIdentity, model: ThemeFile, permission: type[Public] ) -> bool: @@ -107,7 +109,7 @@ def may_view_theme_files_not_logged_in( ) def may_view_auth_not_logged_in( app: IntranetApp, - identity: 'NoIdentity', + identity: NoIdentity, model: Auth, permission: type[Public] ) -> bool: @@ -122,7 +124,7 @@ def may_view_auth_not_logged_in( ) def may_view_public_identity( app: IntranetApp, - identity: 'NoIdentity', + identity: NoIdentity, model: PublicMetadata, permission: type[Public] ) -> bool: diff --git a/src/onegov/intranet/views/exceptionviews.py b/src/onegov/intranet/views/exceptionviews.py index a894a23eea..d1e0ec93a7 100644 --- a/src/onegov/intranet/views/exceptionviews.py +++ b/src/onegov/intranet/views/exceptionviews.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import morepath from onegov.core.security import Public @@ -22,8 +24,8 @@ ) def handle_forbidden_for_homepage( self: HTTPForbidden, - request: 'TownRequest' -) -> 'RenderData | Response': + request: TownRequest +) -> RenderData | Response: """ Usually, the forbidden view offers no way to log in, as we usually do not need that feature (exception views should be simple). diff --git a/src/onegov/landsgemeinde/__init__.py b/src/onegov/landsgemeinde/__init__.py index ea7bb237f6..f21fdf1138 100644 --- a/src/onegov/landsgemeinde/__init__.py +++ b/src/onegov/landsgemeinde/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.landsgemeinde') diff --git a/src/onegov/landsgemeinde/app.py b/src/onegov/landsgemeinde/app.py index 5cd9f612d8..22fd998206 100644 --- a/src/onegov/landsgemeinde/app.py +++ b/src/onegov/landsgemeinde/app.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.framework import current_language_tween_factory from onegov.core.framework import transaction_tween_factory from onegov.core.utils import module_path @@ -24,7 +26,7 @@ class LandsgemeindeApp(TownApp): @property - def pages_cache(self) -> 'RedisCacheRegion': + def pages_cache(self) -> RedisCacheRegion: """ A cache for pages. """ return self.get_cache('pages', 300) @@ -32,12 +34,12 @@ def pages_cache(self) -> 'RedisCacheRegion': @LandsgemeindeApp.setting(section='org', name='create_new_organisation') def get_create_new_organisation_factory( -) -> 'Callable[[LandsgemeindeApp, str], Organisation]': +) -> Callable[[LandsgemeindeApp, str], Organisation]: return create_new_organisation @LandsgemeindeApp.template_variables() -def get_template_variables(request: 'LandsgemeindeRequest') -> 'RenderData': +def get_template_variables(request: LandsgemeindeRequest) -> RenderData: return { 'global_tools': tuple(get_global_tools(request)), 'top_navigation': tuple(get_top_navigation(request)), @@ -71,22 +73,22 @@ def get_theme() -> LandsgemeindeTheme: @LandsgemeindeApp.webasset('ticker') -def get_backend_ticker() -> 'Iterator[str]': +def get_backend_ticker() -> Iterator[str]: yield 'ticker.js' @LandsgemeindeApp.webasset('person_votum') -def get_person_votum() -> 'Iterator[str]': +def get_person_votum() -> Iterator[str]: yield 'person_votum.js' @LandsgemeindeApp.webasset('start_time') -def get_start_time() -> 'Iterator[str]': +def get_start_time() -> Iterator[str]: yield 'start_time.js' @LandsgemeindeApp.webasset('agenda_items') -def get_backend_agenda_items() -> 'Iterator[str]': +def get_backend_agenda_items() -> Iterator[str]: yield 'agenda_items.js' @@ -96,8 +98,8 @@ def get_backend_agenda_items() -> 'Iterator[str]': ) def pages_cache_tween_factory( app: LandsgemeindeApp, - handler: 'Callable[[LandsgemeindeRequest], Response]' -) -> 'Callable[[LandsgemeindeRequest], Response]': + handler: Callable[[LandsgemeindeRequest], Response] +) -> Callable[[LandsgemeindeRequest], Response]: """ Cache pages for 5 minutes. """ @@ -106,13 +108,13 @@ def pages_cache_tween_factory( ) cache_paths_re = compile(r'^({})$'.format('|'.join(cache_paths))) - def should_cache_fn(response: 'Response') -> bool: + def should_cache_fn(response: Response) -> bool: return ( response.status_code == 200 and 'Set-Cookie' not in response.headers ) - def pages_cache_tween(request: 'LandsgemeindeRequest') -> 'Response': + def pages_cache_tween(request: LandsgemeindeRequest) -> Response: # do not cache POST, DELETE etc. if request.method not in ('GET', 'HEAD'): diff --git a/src/onegov/landsgemeinde/collections/__init__.py b/src/onegov/landsgemeinde/collections/__init__.py index a8dd34ebba..6b2197fcb2 100644 --- a/src/onegov/landsgemeinde/collections/__init__.py +++ b/src/onegov/landsgemeinde/collections/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.landsgemeinde.collections.agenda import AgendaItemCollection from onegov.landsgemeinde.collections.assembly import AssemblyCollection from onegov.landsgemeinde.collections.votum import VotumCollection diff --git a/src/onegov/landsgemeinde/collections/agenda.py b/src/onegov/landsgemeinde/collections/agenda.py index 9733e557c7..432136e652 100644 --- a/src/onegov/landsgemeinde/collections/agenda.py +++ b/src/onegov/landsgemeinde/collections/agenda.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.collection import GenericCollection from onegov.landsgemeinde.models import AgendaItem @@ -20,7 +22,7 @@ class AgendaItemCollection(GenericCollection[AgendaItem]): - def __init__(self, session: 'Session', date: 'date | None' = None) -> None: + def __init__(self, session: Session, date: date | None = None) -> None: self.session = session self.date = date @@ -28,7 +30,7 @@ def __init__(self, session: 'Session', date: 'date | None' = None) -> None: def model_class(self) -> type[AgendaItem]: return AgendaItem - def query(self) -> 'Query[AgendaItem]': + def query(self) -> Query[AgendaItem]: query = super().query() if self.date: query = query.join(AgendaItem.assembly) @@ -38,7 +40,7 @@ def query(self) -> 'Query[AgendaItem]': def by_id( self, - id: 'UUID' # type:ignore[override] + id: UUID # type:ignore[override] ) -> AgendaItem | None: return super().query().filter(AgendaItem.id == id).first() @@ -57,7 +59,7 @@ def assembly(self) -> Assembly | None: return query.first() return None - def preloaded_by_assembly(self, assembly: Assembly) -> 'Query[AgendaItem]': + def preloaded_by_assembly(self, assembly: Assembly) -> Query[AgendaItem]: query = self.session.query(AgendaItem) query = query.outerjoin(AgendaItem.vota) query = query.filter(AgendaItem.assembly_id == assembly.id) diff --git a/src/onegov/landsgemeinde/collections/assembly.py b/src/onegov/landsgemeinde/collections/assembly.py index d4dc4e2a23..a39b4a88fa 100644 --- a/src/onegov/landsgemeinde/collections/assembly.py +++ b/src/onegov/landsgemeinde/collections/assembly.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.collection import GenericCollection from onegov.landsgemeinde.models import Assembly from sqlalchemy import desc @@ -17,16 +19,16 @@ class AssemblyCollection(GenericCollection[Assembly]): def model_class(self) -> type[Assembly]: return Assembly - def query(self) -> 'Query[Assembly]': + def query(self) -> Query[Assembly]: return super().query().order_by(desc(Assembly.date)) def by_id( self, - id: 'UUID' # type:ignore[override] + id: UUID # type:ignore[override] ) -> Assembly | None: return self.query().filter(Assembly.id == id).first() - def by_date(self, date_: 'date') -> Assembly | None: + def by_date(self, date_: date) -> Assembly | None: query = self.query().filter(Assembly.date == date_) query = query.options(undefer(Assembly.content)) return query.first() diff --git a/src/onegov/landsgemeinde/collections/votum.py b/src/onegov/landsgemeinde/collections/votum.py index 94d3db408b..8f4cf3f22f 100644 --- a/src/onegov/landsgemeinde/collections/votum.py +++ b/src/onegov/landsgemeinde/collections/votum.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.collection import GenericCollection from onegov.landsgemeinde.models import AgendaItem @@ -18,8 +20,8 @@ class VotumCollection(GenericCollection[Votum]): def __init__( self, - session: 'Session', - date: 'date | None' = None, + session: Session, + date: date | None = None, agenda_item_number: int | None = None ) -> None: self.session = session @@ -30,7 +32,7 @@ def __init__( def model_class(self) -> type[Votum]: return Votum - def query(self) -> 'Query[Votum]': + def query(self) -> Query[Votum]: query = super().query() if self.date or self.agenda_item_number: query = query.join(Votum.agenda_item) @@ -44,7 +46,7 @@ def query(self) -> 'Query[Votum]': def by_id( self, - id: 'UUID' # type:ignore[override] + id: UUID # type:ignore[override] ) -> Votum | None: return super().query().filter(Votum.id == id).first() diff --git a/src/onegov/landsgemeinde/content/__init__.py b/src/onegov/landsgemeinde/content/__init__.py index 4a54205398..5d515af4ee 100644 --- a/src/onegov/landsgemeinde/content/__init__.py +++ b/src/onegov/landsgemeinde/content/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.landsgemeinde.content.initial import create_new_organisation __all__ = ( diff --git a/src/onegov/landsgemeinde/content/initial.py b/src/onegov/landsgemeinde/content/initial.py index 5c0e98a704..f6d0b2ae4a 100644 --- a/src/onegov/landsgemeinde/content/initial.py +++ b/src/onegov/landsgemeinde/content/initial.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import module_path from onegov.org.initial_content import load_content from onegov.org.models import Organisation @@ -9,7 +11,7 @@ def create_new_organisation( - app: 'LandsgemeindeApp', + app: LandsgemeindeApp, name: str, reply_to: str | None = None, forms: None = None, diff --git a/src/onegov/landsgemeinde/custom.py b/src/onegov/landsgemeinde/custom.py index 23e8ef6c31..c65d8e690e 100644 --- a/src/onegov/landsgemeinde/custom.py +++ b/src/onegov/landsgemeinde/custom.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.chat import TextModuleCollection from onegov.core.elements import Link from onegov.core.utils import Bunch @@ -21,8 +23,8 @@ def get_global_tools( - request: 'LandsgemeindeRequest' -) -> 'Iterator[Link | LinkGroup]': + request: LandsgemeindeRequest +) -> Iterator[Link | LinkGroup]: if request.is_logged_in: assert request.current_username is not None @@ -79,8 +81,8 @@ def get_global_tools( def get_top_navigation( - request: 'LandsgemeindeRequest' -) -> 'Iterator[NavigationEntry]': + request: LandsgemeindeRequest +) -> Iterator[NavigationEntry]: yield ( # type:ignore[misc] Bunch(id=-1, access='public', published=True), diff --git a/src/onegov/landsgemeinde/forms/__init__.py b/src/onegov/landsgemeinde/forms/__init__.py index 7d942eada9..e8b002d2e7 100644 --- a/src/onegov/landsgemeinde/forms/__init__.py +++ b/src/onegov/landsgemeinde/forms/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.landsgemeinde.forms.agenda import AgendaItemForm from onegov.landsgemeinde.forms.assembly import AssemblyForm from onegov.landsgemeinde.forms.person import PersonForm diff --git a/src/onegov/landsgemeinde/forms/agenda.py b/src/onegov/landsgemeinde/forms/agenda.py index 5d632ba6de..c745fcfceb 100644 --- a/src/onegov/landsgemeinde/forms/agenda.py +++ b/src/onegov/landsgemeinde/forms/agenda.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form.fields import TagsField from onegov.form.fields import TimeField from onegov.form.fields import UploadField @@ -30,7 +32,7 @@ class AgendaItemForm(NamedFileForm): - request: 'LandsgemeindeRequest' + request: LandsgemeindeRequest number = IntegerField( label=_('Number'), diff --git a/src/onegov/landsgemeinde/forms/assembly.py b/src/onegov/landsgemeinde/forms/assembly.py index 1746cd34a6..812cc7c23c 100644 --- a/src/onegov/landsgemeinde/forms/assembly.py +++ b/src/onegov/landsgemeinde/forms/assembly.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from onegov.form.fields import PanelField from onegov.form.fields import TimeField @@ -27,7 +29,7 @@ class AssemblyForm(NamedFileForm): - request: 'LandsgemeindeRequest' + request: LandsgemeindeRequest date = DateField( label=_('Date'), diff --git a/src/onegov/landsgemeinde/forms/person.py b/src/onegov/landsgemeinde/forms/person.py index 002021b93d..bed716175b 100644 --- a/src/onegov/landsgemeinde/forms/person.py +++ b/src/onegov/landsgemeinde/forms/person.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.org.forms.person import ( PersonForm as OrgPersonForm) diff --git a/src/onegov/landsgemeinde/forms/settings.py b/src/onegov/landsgemeinde/forms/settings.py index afa07257ea..e1f42b8d87 100644 --- a/src/onegov/landsgemeinde/forms/settings.py +++ b/src/onegov/landsgemeinde/forms/settings.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from wtforms.fields import EmailField from onegov.form import Form from onegov.landsgemeinde import _ @@ -27,7 +29,7 @@ class OpenDataSettingsForm(Form): def process_obj( self, - obj: 'Organisation' # type:ignore[override] + obj: Organisation # type:ignore[override] ) -> None: super().process_obj(obj) @@ -37,7 +39,7 @@ def process_obj( def populate_obj( # type:ignore[override] self, - obj: 'Organisation', # type:ignore[override] + obj: Organisation, # type:ignore[override] *args: Any, **kwargs: Any ) -> None: diff --git a/src/onegov/landsgemeinde/forms/votum.py b/src/onegov/landsgemeinde/forms/votum.py index f2de3cfb9e..8fb11dfad0 100644 --- a/src/onegov/landsgemeinde/forms/votum.py +++ b/src/onegov/landsgemeinde/forms/votum.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form.fields import ChosenSelectField from onegov.form.fields import TimeField from onegov.form.fields import TypeAheadField @@ -31,7 +33,7 @@ class VotumForm(NamedFileForm): - request: 'LandsgemeindeRequest' + request: LandsgemeindeRequest number = IntegerField( label=_('Number'), diff --git a/src/onegov/landsgemeinde/i18n.py b/src/onegov/landsgemeinde/i18n.py index 8c34ec64cf..e18d667fc6 100644 --- a/src/onegov/landsgemeinde/i18n.py +++ b/src/onegov/landsgemeinde/i18n.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.i18n.translation_string import TranslationStringFactory _ = TranslationStringFactory('onegov.landsgemeinde') diff --git a/src/onegov/landsgemeinde/layouts/__init__.py b/src/onegov/landsgemeinde/layouts/__init__.py index 0a6981d772..3402c91a75 100644 --- a/src/onegov/landsgemeinde/layouts/__init__.py +++ b/src/onegov/landsgemeinde/layouts/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.landsgemeinde.layouts.agenda import AgendaItemCollectionLayout from onegov.landsgemeinde.layouts.agenda import AgendaItemLayout from onegov.landsgemeinde.layouts.assembly import AssemblyCollectionLayout diff --git a/src/onegov/landsgemeinde/layouts/agenda.py b/src/onegov/landsgemeinde/layouts/agenda.py index adbe40279a..1366a07f69 100644 --- a/src/onegov/landsgemeinde/layouts/agenda.py +++ b/src/onegov/landsgemeinde/layouts/agenda.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.elements import Confirm from onegov.core.elements import Intercooler @@ -65,13 +67,13 @@ def editbar_links(self) -> list[Link | LinkGroup] | None: class AgendaItemLayout(DefaultLayout): - model: 'AgendaItem' - request: 'LandsgemeindeRequest' + model: AgendaItem + request: LandsgemeindeRequest def __init__( self, - model: 'AgendaItem', - request: 'LandsgemeindeRequest' + model: AgendaItem, + request: LandsgemeindeRequest ) -> None: super().__init__(model, request) @@ -152,7 +154,7 @@ def editbar_links(self) -> list[Link | LinkGroup] | None: def editbar_links_for_votum( self, - votum: 'Votum' + votum: Votum ) -> list[Link | LinkGroup] | None: if self.request.is_manager: diff --git a/src/onegov/landsgemeinde/layouts/assembly.py b/src/onegov/landsgemeinde/layouts/assembly.py index ea6484bd89..738737a0b8 100644 --- a/src/onegov/landsgemeinde/layouts/assembly.py +++ b/src/onegov/landsgemeinde/layouts/assembly.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.elements import Confirm from onegov.core.elements import Intercooler @@ -137,12 +139,12 @@ def editbar_links(self) -> list[Link | LinkGroup] | None: class AssemblyTickerLayout(DefaultLayout): - model: 'Assembly' + model: Assembly def __init__( self, - model: 'Assembly', - request: 'LandsgemeindeRequest' + model: Assembly, + request: LandsgemeindeRequest ) -> None: super().__init__(model, request) diff --git a/src/onegov/landsgemeinde/layouts/default.py b/src/onegov/landsgemeinde/layouts/default.py index 6f7e4ecfb5..c4c8fc2938 100644 --- a/src/onegov/landsgemeinde/layouts/default.py +++ b/src/onegov/landsgemeinde/layouts/default.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.static import StaticFile from onegov.landsgemeinde import _ @@ -16,9 +18,9 @@ class DefaultLayout(BaseDefaultLayout): - request: 'LandsgemeindeRequest' + request: LandsgemeindeRequest - def __init__(self, model: Any, request: 'LandsgemeindeRequest') -> None: + def __init__(self, model: Any, request: LandsgemeindeRequest) -> None: super().__init__(model, request) self.custom_body_attributes['data-websocket-endpoint'] = '' @@ -38,7 +40,7 @@ def assembly_title(self, assembly: Assembly) -> str: def agenda_item_title( self, - agenda_item: 'AgendaItem', + agenda_item: AgendaItem, short: bool = False ) -> str: if agenda_item.irrelevant: @@ -56,7 +58,7 @@ def agenda_item_title( agenda_item.title ) - def votum_title(self, votum: 'Votum') -> str: + def votum_title(self, votum: Votum) -> str: return '{} {}'.format( self.request.translate(_('Votum')), votum.number diff --git a/src/onegov/landsgemeinde/layouts/votum.py b/src/onegov/landsgemeinde/layouts/votum.py index 40b44d5f61..2d3257b2d6 100644 --- a/src/onegov/landsgemeinde/layouts/votum.py +++ b/src/onegov/landsgemeinde/layouts/votum.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.elements import Link from onegov.landsgemeinde import _ diff --git a/src/onegov/landsgemeinde/models/__init__.py b/src/onegov/landsgemeinde/models/__init__.py index ffcac61281..6cc67d6d7d 100644 --- a/src/onegov/landsgemeinde/models/__init__.py +++ b/src/onegov/landsgemeinde/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.landsgemeinde.models.agenda import AgendaItem from onegov.landsgemeinde.models.assembly import Assembly from onegov.landsgemeinde.models.file import LandsgemeindeFile diff --git a/src/onegov/landsgemeinde/models/agenda.py b/src/onegov/landsgemeinde/models/agenda.py index 966313d62c..76535fc636 100644 --- a/src/onegov/landsgemeinde/models/agenda.py +++ b/src/onegov/landsgemeinde/models/agenda.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import content_property from onegov.core.orm.mixins import dict_markup_property @@ -35,7 +37,7 @@ AgendaItemState: TypeAlias = Literal['scheduled', 'ongoing', 'completed'] -STATES: dict['AgendaItemState', 'TranslationString'] = { +STATES: dict[AgendaItemState, TranslationString] = { 'scheduled': _('scheduled'), 'ongoing': _('ongoing'), 'completed': _('completed') @@ -58,33 +60,33 @@ class AgendaItem( } #: the internal id of the agenda item - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the external id of the agenda item - number: 'Column[int]' = Column(Integer, nullable=False) + number: Column[int] = Column(Integer, nullable=False) #: the state of the agenda item - state: 'Column[AgendaItemState]' = Column( + state: Column[AgendaItemState] = Column( Enum(*STATES.keys(), name='agenda_item_state'), # type:ignore nullable=False ) #: True if the item has been declared irrelevant - irrelevant: 'Column[bool]' = Column(Boolean, nullable=False, default=False) + irrelevant: Column[bool] = Column(Boolean, nullable=False, default=False) #: True if the item has been tacitly accepted - tacitly_accepted: 'Column[bool]' = Column( + tacitly_accepted: Column[bool] = Column( Boolean, nullable=False, default=False ) #: the assembly this agenda item belongs to - assembly_id: 'Column[uuid.UUID]' = Column( + assembly_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey( 'landsgemeinde_assemblies.id', @@ -94,13 +96,13 @@ class AgendaItem( nullable=False ) - assembly: 'relationship[Assembly]' = relationship( + assembly: relationship[Assembly] = relationship( 'Assembly', back_populates='agenda_items', ) #: Title of the agenda item (not translated) - title: 'Column[str]' = Column(Text, nullable=False, default=lambda: '') + title: Column[str] = Column(Text, nullable=False, default=lambda: '') #: The memorial of the assembly memorial_pdf = NamedFile(cls=LandsgemeindeFile) @@ -121,7 +123,7 @@ class AgendaItem( resolution_tags: dict_property[list[str] | None] = content_property() #: An agenda item contains n vota - vota: 'relationship[list[Votum]]' = relationship( + vota: relationship[list[Votum]] = relationship( Votum, cascade='all, delete-orphan', back_populates='agenda_item', @@ -135,7 +137,7 @@ def stamp(self) -> None: self.last_modified = self.timestamp() @property - def date(self) -> 'date_t': + def date(self) -> date_t: return self.assembly.date @property diff --git a/src/onegov/landsgemeinde/models/assembly.py b/src/onegov/landsgemeinde/models/assembly.py index e52b1c871a..695b4c932b 100644 --- a/src/onegov/landsgemeinde/models/assembly.py +++ b/src/onegov/landsgemeinde/models/assembly.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import dict_markup_property from onegov.core.orm.mixins import ContentMixin @@ -32,7 +34,7 @@ AssemblyState: TypeAlias = Literal['scheduled', 'ongoing', 'completed'] -STATES: dict['AssemblyState', 'TranslationString'] = { +STATES: dict[AssemblyState, TranslationString] = { 'scheduled': _('scheduled'), 'ongoing': _('ongoing'), 'completed': _('completed') @@ -59,30 +61,30 @@ def es_suggestion(self) -> tuple[str, ...]: ) #: Internal number of the event - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the state of the assembly - state: 'Column[AssemblyState]' = Column( + state: Column[AssemblyState] = Column( Enum(*STATES.keys(), name='assembly_state'), # type:ignore[arg-type] nullable=False ) #: The date of the assembly - date: 'Column[date_t]' = Column(Date, nullable=False, unique=True) + date: Column[date_t] = Column(Date, nullable=False, unique=True) #: True if this is an extraordinary assembly - extraordinary: 'Column[bool]' = Column( + extraordinary: Column[bool] = Column( Boolean, nullable=False, default=False ) #: The video URL of the assembly - video_url: 'Column[str | None]' = Column(Text, nullable=True) + video_url: Column[str | None] = Column(Text, nullable=True) #: The memorial of the assembly memorial_pdf = NamedFile(cls=LandsgemeindeFile) @@ -106,14 +108,14 @@ def es_suggestion(self) -> tuple[str, ...]: overview = dict_markup_property('content') #: An assembly contains n agenda items - agenda_items: 'relationship[list[AgendaItem]]' = relationship( + agenda_items: relationship[list[AgendaItem]] = relationship( AgendaItem, cascade='all, delete-orphan', back_populates='assembly', order_by='AgendaItem.number', ) - last_modified: 'Column[datetime | None]' = Column(UTCDateTime) + last_modified: Column[datetime | None] = Column(UTCDateTime) def stamp(self) -> None: self.last_modified = self.timestamp() diff --git a/src/onegov/landsgemeinde/models/file.py b/src/onegov/landsgemeinde/models/file.py index 581ac84ede..fbae07734a 100644 --- a/src/onegov/landsgemeinde/models/file.py +++ b/src/onegov/landsgemeinde/models/file.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.file.models.file import File from onegov.file.models.file import SearchableFile diff --git a/src/onegov/landsgemeinde/models/mixins.py b/src/onegov/landsgemeinde/models/mixins.py index b65c706e00..81235660ef 100644 --- a/src/onegov/landsgemeinde/models/mixins.py +++ b/src/onegov/landsgemeinde/models/mixins.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date from datetime import datetime from onegov.core.utils import append_query_param @@ -19,7 +21,7 @@ class StartTimeMixin: #: The local start time - start_time: 'Column[time | None]' = Column(Time, nullable=True) + start_time: Column[time | None] = Column(Time, nullable=True) def start(self) -> None: self.start_time = to_timezone(utcnow(), 'Europe/Zurich').time() @@ -29,7 +31,7 @@ class TimestampedVideoMixin(StartTimeMixin): if TYPE_CHECKING: # forward declare required attributes - assembly: 'Assembly | relationship[Assembly]' + assembly: Assembly | relationship[Assembly] #: The manual video timestamp of this agenda item video_timestamp: dict_property[str | None] = content_property() diff --git a/src/onegov/landsgemeinde/models/suggestion.py b/src/onegov/landsgemeinde/models/suggestion.py index 9b9ab5db40..15fa0ae72a 100644 --- a/src/onegov/landsgemeinde/models/suggestion.py +++ b/src/onegov/landsgemeinde/models/suggestion.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.landsgemeinde.models import AgendaItem from onegov.landsgemeinde.models import Assembly from onegov.landsgemeinde.models import Votum @@ -18,7 +20,7 @@ class Suggestion: """ - def __init__(self, session: 'Session', term: str | None = '') -> None: + def __init__(self, session: Session, term: str | None = '') -> None: self.session = session self.term = term self.limit = 5 @@ -26,13 +28,13 @@ def __init__(self, session: 'Session', term: str | None = '') -> None: @property def votum_expression( self - ) -> 'ColumnElement[str] | ColumnElement[str | None]': + ) -> ColumnElement[str] | ColumnElement[str | None]: raise NotImplementedError() @property def person_expressions( self - ) -> tuple['ColumnElement[str] | ColumnElement[str | None]', ...]: + ) -> tuple[ColumnElement[str] | ColumnElement[str | None], ...]: raise NotImplementedError() def query(self) -> list[str]: @@ -44,7 +46,7 @@ def query(self) -> list[str]: for expression in self.person_expressions: query = self.session.query(expression) query = query.filter( - expression.isnot(None), + expression.isnot(None), # type:ignore[no-untyped-call] func.trim(expression) != '', ) if self.term: @@ -60,7 +62,7 @@ def query(self) -> list[str]: query = query.join(AgendaItem) query = query.join(Assembly) query = query.filter( - self.votum_expression.isnot(None), + self.votum_expression.isnot(None), # type:ignore[no-untyped-call] func.trim(self.votum_expression) != '', ) if self.term: @@ -83,42 +85,42 @@ def query(self) -> list[str]: class PersonNameSuggestion(Suggestion): @property - def votum_expression(self) -> 'ColumnElement[str | None]': + def votum_expression(self) -> ColumnElement[str | None]: return Votum.person_name @property - def person_expressions(self) -> tuple['ColumnElement[str]']: + def person_expressions(self) -> tuple[ColumnElement[str]]: return (func.concat(Person.first_name, ' ', Person.last_name),) class PersonFunctionSuggestion(Suggestion): @property - def votum_expression(self) -> 'ColumnElement[str | None]': + def votum_expression(self) -> ColumnElement[str | None]: return Votum.person_function @property - def person_expressions(self) -> tuple['ColumnElement[str | None]', ...]: + def person_expressions(self) -> tuple[ColumnElement[str | None], ...]: return (Person.function, Person.profession) class PersonPlaceSuggestion(Suggestion): @property - def votum_expression(self) -> 'ColumnElement[str | None]': + def votum_expression(self) -> ColumnElement[str | None]: return Votum.person_place @property - def person_expressions(self) -> tuple['ColumnElement[str | None]', ...]: + def person_expressions(self) -> tuple[ColumnElement[str | None], ...]: return (Person.postal_code_city, Person.location_code_city) class PersonPoliticalAffiliationSuggestion(Suggestion): @property - def votum_expression(self) -> 'ColumnElement[str | None]': + def votum_expression(self) -> ColumnElement[str | None]: return Votum.person_political_affiliation @property - def person_expressions(self) -> tuple['ColumnElement[str | None]', ...]: + def person_expressions(self) -> tuple[ColumnElement[str | None], ...]: return (Person.parliamentary_group, Person.political_party) diff --git a/src/onegov/landsgemeinde/models/votum.py b/src/onegov/landsgemeinde/models/votum.py index 9148c9243f..07e849bdca 100644 --- a/src/onegov/landsgemeinde/models/votum.py +++ b/src/onegov/landsgemeinde/models/votum.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import ContentMixin from onegov.core.orm.mixins import dict_markup_property @@ -29,7 +31,7 @@ VotumState: TypeAlias = Literal['scheduled', 'ongoing', 'completed'] -STATES: dict['VotumState', 'TranslationString'] = { +STATES: dict[VotumState, TranslationString] = { 'scheduled': _('scheduled'), 'ongoing': _('ongoing'), 'completed': _('completed') @@ -59,20 +61,20 @@ def es_suggestion(self) -> tuple[str, ...]: return () #: the internal id of the votum - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the state of the votum - state: 'Column[VotumState]' = Column( + state: Column[VotumState] = Column( Enum(*STATES.keys(), name='votum_item_state'), # type:ignore[arg-type] nullable=False ) #: the external id of the agenda item - number: 'Column[int]' = Column(Integer, nullable=False) + number: Column[int] = Column(Integer, nullable=False) #: The main text of the votum text = dict_markup_property('content') @@ -84,25 +86,25 @@ def es_suggestion(self) -> tuple[str, ...]: statement_of_reasons = dict_markup_property('content') #: The name of the person - person_name: 'Column[str | None]' = Column(Text, nullable=True) + person_name: Column[str | None] = Column(Text, nullable=True) #: The function of the person - person_function: 'Column[str | None]' = Column(Text, nullable=True) + person_function: Column[str | None] = Column(Text, nullable=True) #: The place of the person - person_place: 'Column[str | None]' = Column(Text, nullable=True) + person_place: Column[str | None] = Column(Text, nullable=True) #: The political affiliation of the person (party or parliamentary group) - person_political_affiliation: 'Column[str | None]' = Column( + person_political_affiliation: Column[str | None] = Column( Text, nullable=True ) #: A picture of the person - person_picture: 'Column[str | None]' = Column(Text, nullable=True) + person_picture: Column[str | None] = Column(Text, nullable=True) #: the agenda this votum belongs to - agenda_item_id: 'Column[uuid.UUID]' = Column( + agenda_item_id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] ForeignKey( 'landsgemeinde_agenda_items.id', @@ -112,13 +114,13 @@ def es_suggestion(self) -> tuple[str, ...]: nullable=False ) - agenda_item: 'relationship[AgendaItem]' = relationship( + agenda_item: relationship[AgendaItem] = relationship( 'AgendaItem', back_populates='vota', ) @property - def date(self) -> 'date_t': + def date(self) -> date_t: return self.agenda_item.date @property @@ -126,7 +128,7 @@ def agenda_item_number(self) -> int: return self.agenda_item.number @property - def assembly(self) -> 'Assembly': # type:ignore[override] + def assembly(self) -> Assembly: # type:ignore[override] return self.agenda_item.assembly @property diff --git a/src/onegov/landsgemeinde/path.py b/src/onegov/landsgemeinde/path.py index 4eebbdab13..e285f75a59 100644 --- a/src/onegov/landsgemeinde/path.py +++ b/src/onegov/landsgemeinde/path.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.converters import extended_date_converter from onegov.landsgemeinde.app import LandsgemeindeApp from onegov.landsgemeinde.collections import AgendaItemCollection @@ -30,7 +32,7 @@ def get_assemblies(app: LandsgemeindeApp) -> AssemblyCollection: path='/landsgemeinde/{date}', converters={'date': extended_date_converter} ) -def get_assembly(app: LandsgemeindeApp, date: 'date') -> Assembly | None: +def get_assembly(app: LandsgemeindeApp, date: date) -> Assembly | None: return AssemblyCollection(app.session()).by_date(date) @@ -41,7 +43,7 @@ def get_assembly(app: LandsgemeindeApp, date: 'date') -> Assembly | None: ) def get_agenda_items( app: LandsgemeindeApp, - date: 'date' + date: date ) -> AgendaItemCollection: return AgendaItemCollection(app.session(), date) @@ -53,7 +55,7 @@ def get_agenda_items( ) def get_agenda_item( app: LandsgemeindeApp, - date: 'date', + date: date, number: int ) -> AgendaItem | None: return AgendaItemCollection(app.session(), date).by_number(number) @@ -69,7 +71,7 @@ def get_agenda_item( ) def get_vota( app: LandsgemeindeApp, - date: 'date', + date: date, agenda_item_number: int ) -> VotumCollection: return VotumCollection(app.session(), date, agenda_item_number) @@ -86,7 +88,7 @@ def get_vota( ) def get_votum( app: LandsgemeindeApp, - date: 'date', + date: date, agenda_item_number: int, number: int ) -> Votum | None: diff --git a/src/onegov/landsgemeinde/request.py b/src/onegov/landsgemeinde/request.py index 19d8b4af9a..5832b36ca1 100644 --- a/src/onegov/landsgemeinde/request.py +++ b/src/onegov/landsgemeinde/request.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.town6.request import TownRequest diff --git a/src/onegov/landsgemeinde/theme/__init__.py b/src/onegov/landsgemeinde/theme/__init__.py index 65f10254e1..f1faffcd29 100644 --- a/src/onegov/landsgemeinde/theme/__init__.py +++ b/src/onegov/landsgemeinde/theme/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import module_path from onegov.town6.theme import TownTheme diff --git a/src/onegov/landsgemeinde/upgrade.py b/src/onegov/landsgemeinde/upgrade.py index b5d4fe178d..fe99547e55 100644 --- a/src/onegov/landsgemeinde/upgrade.py +++ b/src/onegov/landsgemeinde/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + from onegov.core.upgrade import upgrade_task from onegov.core.upgrade import UpgradeContext from onegov.core.orm.types import UTCDateTime diff --git a/src/onegov/landsgemeinde/utils.py b/src/onegov/landsgemeinde/utils.py index 6788c2112f..e695d5023c 100644 --- a/src/onegov/landsgemeinde/utils.py +++ b/src/onegov/landsgemeinde/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.templates import render_macro from onegov.landsgemeinde.layouts import DefaultLayout from onegov.landsgemeinde.models import AgendaItem @@ -18,8 +20,8 @@ def update_ticker( - request: 'LandsgemeindeRequest', - updated: 'Collection[Assembly | AgendaItem | Votum]' + request: LandsgemeindeRequest, + updated: Collection[Assembly | AgendaItem | Votum] ) -> None: """ Updates the ticker by a set of updated assemblies, agenda items or vota. @@ -97,7 +99,7 @@ def ensure_states( def set_state( item: Assembly | AgendaItem | Votum, - state: 'AssemblyState | AgendaItemState | VotumState' + state: AssemblyState | AgendaItemState | VotumState ) -> None: if item.state != state: item.state = state @@ -105,7 +107,7 @@ def set_state( def set_by_children( parent: Assembly | AgendaItem, - children: 'Iterable[AgendaItem] | Iterable[Votum]' + children: Iterable[AgendaItem] | Iterable[Votum] ) -> None: if all(x.state == 'scheduled' for x in children): if parent.state != 'ongoing': @@ -117,7 +119,7 @@ def set_by_children( if isinstance(parent, AgendaItem): parent.start() - def set_vota(vota: 'Iterable[Votum]', state: 'VotumState') -> None: + def set_vota(vota: Iterable[Votum], state: VotumState) -> None: for votum in vota: set_state(votum, state) @@ -132,8 +134,8 @@ def set_start_time(item: AgendaItem | Votum) -> None: updated.add(item) def set_agenda_items( - agenda_items: 'Iterable[AgendaItem]', - state: 'AgendaItemState' + agenda_items: Iterable[AgendaItem], + state: AgendaItemState ) -> None: for agenda_item in agenda_items: diff --git a/src/onegov/landsgemeinde/views/agenda.py b/src/onegov/landsgemeinde/views/agenda.py index 118f7213a7..6f3b87f108 100644 --- a/src/onegov/landsgemeinde/views/agenda.py +++ b/src/onegov/landsgemeinde/views/agenda.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.elements import BackLink, Link from onegov.core.security import Private @@ -30,9 +32,9 @@ ) def add_agenda_item( self: AgendaItemCollection, - request: 'LandsgemeindeRequest', + request: LandsgemeindeRequest, form: AgendaItemForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): agenda_item = self.add(**form.get_useful_data()) @@ -65,8 +67,8 @@ def add_agenda_item( ) def view_agenda_item( self: AgendaItem, - request: 'LandsgemeindeRequest' -) -> 'RenderData': + request: LandsgemeindeRequest +) -> RenderData: layout = AgendaItemLayout(self, request) agenda_items = self.assembly.agenda_items @@ -100,9 +102,9 @@ def view_agenda_item( ) def edit_agenda_item( self: AgendaItem, - request: 'LandsgemeindeRequest', + request: LandsgemeindeRequest, form: AgendaItemForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): form.populate_obj(self) @@ -133,7 +135,7 @@ def edit_agenda_item( ) def delete_agenda_item( self: AgendaItem, - request: 'LandsgemeindeRequest' + request: LandsgemeindeRequest ) -> None: request.assert_valid_csrf_token() diff --git a/src/onegov/landsgemeinde/views/assembly.py b/src/onegov/landsgemeinde/views/assembly.py index f65d122d17..a1b11462dd 100644 --- a/src/onegov/landsgemeinde/views/assembly.py +++ b/src/onegov/landsgemeinde/views/assembly.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.elements import Link from onegov.core.security import Private @@ -31,8 +33,8 @@ ) def view_assemblies( self: AssemblyCollection, - request: 'LandsgemeindeRequest' -) -> 'RenderData': + request: LandsgemeindeRequest +) -> RenderData: layout = AssemblyCollectionLayout(self, request) @@ -53,9 +55,9 @@ def view_assemblies( ) def add_assembly( self: AssemblyCollection, - request: 'LandsgemeindeRequest', + request: LandsgemeindeRequest, form: AssemblyForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): assembly = self.add(**form.get_useful_data()) @@ -82,8 +84,8 @@ def add_assembly( ) def view_assembly( self: Assembly, - request: 'LandsgemeindeRequest' -) -> 'RenderData | Response': + request: LandsgemeindeRequest +) -> RenderData | Response: layout = AssemblyLayout(self, request) @@ -106,8 +108,8 @@ def view_assembly( ) def view_assembly_ticker( self: Assembly, - request: 'LandsgemeindeRequest' -) -> 'RenderData': + request: LandsgemeindeRequest +) -> RenderData: layout = AssemblyTickerLayout(self, request) @@ -132,11 +134,11 @@ def view_assembly_ticker( ) def view_assembly_ticker_head( self: Assembly, - request: 'LandsgemeindeRequest' + request: LandsgemeindeRequest ) -> None: @request.after - def add_headers(response: 'Response') -> None: + def add_headers(response: Response) -> None: last_modified = self.last_modified or self.modified or self.created if last_modified: response.headers.add( @@ -153,8 +155,8 @@ def add_headers(response: 'Response') -> None: ) def view_assembly_states( self: Assembly, - request: 'LandsgemeindeRequest' -) -> 'RenderData': + request: LandsgemeindeRequest +) -> RenderData: layout = AssemblyLayout(self, request) layout.editbar_links = [] @@ -182,9 +184,9 @@ def view_assembly_states( ) def edit_assembly( self: Assembly, - request: 'LandsgemeindeRequest', + request: LandsgemeindeRequest, form: AssemblyForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): form.populate_obj(self) @@ -213,7 +215,7 @@ def edit_assembly( request_method='DELETE', permission=Private ) -def delete_assembly(self: Assembly, request: 'LandsgemeindeRequest') -> None: +def delete_assembly(self: Assembly, request: LandsgemeindeRequest) -> None: request.assert_valid_csrf_token() @@ -229,8 +231,8 @@ def delete_assembly(self: Assembly, request: 'LandsgemeindeRequest') -> None: ) def view_assembly_open_data( self: Assembly, - request: 'LandsgemeindeRequest' -) -> 'RenderData | Response': + request: LandsgemeindeRequest +) -> RenderData | Response: layout = AssemblyLayout(self, request) @@ -254,8 +256,8 @@ def view_assembly_open_data( ) def view_assembly_json( self: Assembly, - request: 'LandsgemeindeRequest' -) -> 'RenderData': + request: LandsgemeindeRequest +) -> RenderData: agenda_items = ( AgendaItemCollection(request.session) @@ -265,10 +267,10 @@ def view_assembly_json( def text(text: str | None) -> str | None: return text.strip() if text else None - def link(file: 'File | None') -> str | None: + def link(file: File | None) -> str | None: return request.link(file) if file else None - def isoformat(date_: 'date | datetime | None') -> str | None: + def isoformat(date_: date | datetime | None) -> str | None: return date_.isoformat() if date_ else None return { diff --git a/src/onegov/landsgemeinde/views/homepage.py b/src/onegov/landsgemeinde/views/homepage.py index 0d60134736..ee9d045868 100644 --- a/src/onegov/landsgemeinde/views/homepage.py +++ b/src/onegov/landsgemeinde/views/homepage.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.security import Public @@ -23,8 +25,8 @@ ) def landsgemeinde_view_org( self: Organisation, - request: 'LandsgemeindeRequest' -) -> 'RenderData | Response': + request: LandsgemeindeRequest +) -> RenderData | Response: current_assembly = AssemblyCollection(request.session).query().filter( Assembly.state == 'ongoing').order_by( diff --git a/src/onegov/landsgemeinde/views/opendata_swiss.py b/src/onegov/landsgemeinde/views/opendata_swiss.py index 28dc105ab3..72ca575be6 100644 --- a/src/onegov/landsgemeinde/views/opendata_swiss.py +++ b/src/onegov/landsgemeinde/views/opendata_swiss.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from io import BytesIO from onegov.core.security import Public from onegov.landsgemeinde import _ @@ -37,7 +39,7 @@ def sub( ) def view_rdf( self: Organisation, - request: 'LandsgemeindeRequest' + request: LandsgemeindeRequest ) -> bytes: """ Returns an XML / RDF / DCAT-AP for Switzerland format for @@ -55,7 +57,7 @@ def view_rdf( raise HTTPNotImplemented() @request.after - def set_headers(response: 'Response') -> None: + def set_headers(response: Response) -> None: response.headers['Content-Type'] = 'application/rdf+xml; charset=UTF-8' layout = DefaultLayout(self, request) diff --git a/src/onegov/landsgemeinde/views/person.py b/src/onegov/landsgemeinde/views/person.py index 202093570f..315bb23209 100644 --- a/src/onegov/landsgemeinde/views/person.py +++ b/src/onegov/landsgemeinde/views/person.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.landsgemeinde import _ from onegov.core.security import Private from onegov.landsgemeinde.app import LandsgemeindeApp @@ -23,9 +25,9 @@ ) def landsgemeinde_handle_new_person( self: PersonCollection, - request: 'LandsgemeindeRequest', + request: LandsgemeindeRequest, form: PersonForm -) -> 'RenderData | Response': +) -> RenderData | Response: form.location_code_city.label.text = _('Location') layout = PersonCollectionLayout(self, request) @@ -41,9 +43,9 @@ def landsgemeinde_handle_new_person( ) def landsgemeinde_handle_edit_person( self: Person, - request: 'LandsgemeindeRequest', + request: LandsgemeindeRequest, form: PersonForm -) -> 'RenderData | Response': +) -> RenderData | Response: form.location_code_city.label.text = _('Location') layout = PersonLayout(self, request) diff --git a/src/onegov/landsgemeinde/views/search.py b/src/onegov/landsgemeinde/views/search.py index ded65c259f..727715a005 100644 --- a/src/onegov/landsgemeinde/views/search.py +++ b/src/onegov/landsgemeinde/views/search.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Public from onegov.landsgemeinde import LandsgemeindeApp from onegov.landsgemeinde.layouts import DefaultLayout @@ -15,7 +17,7 @@ @LandsgemeindeApp.html(model=Search, template='search.pt', permission=Public) def landsgemeinde_search( - self: Search['Base'], - request: 'LandsgemeindeRequest' -) -> 'RenderData | Response': + self: Search[Base], + request: LandsgemeindeRequest +) -> RenderData | Response: return search(self, request, DefaultLayout(self, request)) diff --git a/src/onegov/landsgemeinde/views/settings.py b/src/onegov/landsgemeinde/views/settings.py index f28d170d0c..9ae4583ed7 100644 --- a/src/onegov/landsgemeinde/views/settings.py +++ b/src/onegov/landsgemeinde/views/settings.py @@ -1,4 +1,6 @@ """ The settings view, defining things like the logo or color of the org. """ +from __future__ import annotations + from onegov.core.security import Secret from onegov.org import _ from onegov.org.models import Organisation @@ -21,8 +23,8 @@ ) def town_handle_chat_settings( self: Organisation, - request: 'TownRequest', + request: TownRequest, form: OpenDataSettingsForm -) -> 'RenderData | Response': +) -> RenderData | Response: layout = SettingsLayout(self, request, _('Open Data')) return handle_generic_settings(self, request, form, _('Open Data'), layout) diff --git a/src/onegov/landsgemeinde/views/suggestion.py b/src/onegov/landsgemeinde/views/suggestion.py index e6b9875f40..2ea528b504 100644 --- a/src/onegov/landsgemeinde/views/suggestion.py +++ b/src/onegov/landsgemeinde/views/suggestion.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.security import Private from onegov.landsgemeinde import LandsgemeindeApp from onegov.landsgemeinde.models import PersonFunctionSuggestion @@ -18,8 +20,8 @@ ) def suggest_person_function( self: PersonFunctionSuggestion, - request: 'LandsgemeindeRequest' -) -> 'JSON_ro': + request: LandsgemeindeRequest +) -> JSON_ro: return self.query() @@ -29,8 +31,8 @@ def suggest_person_function( ) def suggest_person_name( self: PersonNameSuggestion, - request: 'LandsgemeindeRequest' -) -> 'JSON_ro': + request: LandsgemeindeRequest +) -> JSON_ro: return self.query() @@ -40,8 +42,8 @@ def suggest_person_name( ) def suggest_person_place( self: PersonPlaceSuggestion, - request: 'LandsgemeindeRequest' -) -> 'JSON_ro': + request: LandsgemeindeRequest +) -> JSON_ro: return self.query() @@ -51,6 +53,6 @@ def suggest_person_place( ) def suggest_person_political_affiliation( self: PersonPoliticalAffiliationSuggestion, - request: 'LandsgemeindeRequest' -) -> 'JSON_ro': + request: LandsgemeindeRequest +) -> JSON_ro: return self.query() diff --git a/src/onegov/landsgemeinde/views/votum.py b/src/onegov/landsgemeinde/views/votum.py index 8c94f81182..651daf04da 100644 --- a/src/onegov/landsgemeinde/views/votum.py +++ b/src/onegov/landsgemeinde/views/votum.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from morepath import redirect from onegov.core.elements import BackLink, Link from onegov.core.security import Private @@ -28,9 +30,9 @@ ) def add_votum( self: VotumCollection, - request: 'LandsgemeindeRequest', + request: LandsgemeindeRequest, form: VotumForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): votum = self.add(**form.get_useful_data()) @@ -67,9 +69,9 @@ def add_votum( ) def edit_votum( self: Votum, - request: 'LandsgemeindeRequest', + request: LandsgemeindeRequest, form: VotumForm -) -> 'RenderData | Response': +) -> RenderData | Response: if form.submitted(request): form.populate_obj(self) @@ -101,7 +103,7 @@ def edit_votum( request_method='DELETE', permission=Private ) -def delete_votum(self: Votum, request: 'LandsgemeindeRequest') -> None: +def delete_votum(self: Votum, request: LandsgemeindeRequest) -> None: request.assert_valid_csrf_token() diff --git a/src/onegov/newsletter/__init__.py b/src/onegov/newsletter/__init__.py index 3192d29539..3930519274 100644 --- a/src/onegov/newsletter/__init__.py +++ b/src/onegov/newsletter/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.newsletter.models import Newsletter, Recipient, Subscription from onegov.newsletter.collection import ( NewsletterCollection, RecipientCollection diff --git a/src/onegov/newsletter/collection.py b/src/onegov/newsletter/collection.py index 12dd78de4c..8983bb801d 100644 --- a/src/onegov/newsletter/collection.py +++ b/src/onegov/newsletter/collection.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import normalize_for_url, is_uuid from onegov.newsletter import Newsletter, Recipient from onegov.newsletter.errors import AlreadyExistsError @@ -13,10 +15,10 @@ class NewsletterCollection: - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session - def query(self) -> 'Query[Newsletter]': + def query(self) -> Query[Newsletter]: return self.session.query(Newsletter) def by_name(self, name: str) -> Newsletter | None: @@ -25,11 +27,11 @@ def by_name(self, name: str) -> Newsletter | None: def add( self, title: str, - html: 'Markup', + html: Markup, lead: str | None = None, meta: dict[str, Any] | None = None, content: dict[str, Any] | None = None, - scheduled: 'datetime | None' = None + scheduled: datetime | None = None ) -> Newsletter: name = normalize_for_url(title) @@ -59,13 +61,13 @@ def delete(self, newsletter: Newsletter) -> None: class RecipientCollection: - def __init__(self, session: 'Session'): + def __init__(self, session: Session): self.session = session - def query(self) -> 'Query[Recipient]': + def query(self) -> Query[Recipient]: return self.session.query(Recipient) - def by_id(self, id: 'str | UUID') -> Recipient | None: + def by_id(self, id: str | UUID) -> Recipient | None: if is_uuid(id): return self.query().filter(Recipient.id == id).first() return None @@ -82,7 +84,7 @@ def by_address( return query.first() - def ordered_by_status_address(self) -> 'Query[Recipient]': + def ordered_by_status_address(self) -> Query[Recipient]: """ Orders the recipients by status and address. """ return self.query().order_by(Recipient.confirmed, Recipient.address) diff --git a/src/onegov/newsletter/errors.py b/src/onegov/newsletter/errors.py index d00579fbbc..71fbed94f2 100644 --- a/src/onegov/newsletter/errors.py +++ b/src/onegov/newsletter/errors.py @@ -1,3 +1,6 @@ +from __future__ import annotations + + class NewsletterException(Exception): pass diff --git a/src/onegov/newsletter/models.py b/src/onegov/newsletter/models.py index 1c7e2b63e4..f9263b3682 100644 --- a/src/onegov/newsletter/models.py +++ b/src/onegov/newsletter/models.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from email_validator import validate_email from onegov.core.crypto import random_token from onegov.core.orm import Base @@ -59,7 +61,7 @@ def es_public(self) -> bool: return self.sent is not None #: the name of the newsletter, derived from the title - name: 'Column[str]' = Column(Text, nullable=False, primary_key=True) + name: Column[str] = Column(Text, nullable=False, primary_key=True) @validates('name') def validate_name(self, key: str, name: str) -> str: @@ -70,33 +72,33 @@ def validate_name(self, key: str, name: str) -> str: return name #: the title of the newsletter - title: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) #: the optional lead or editorial of the newsletter - lead: 'Column[str | None]' = Column(Text, nullable=True) + lead: Column[str | None] = Column(Text, nullable=True) #: the content of the newsletter in html, this is not just the partial #: content, but the actual, fully rendered html content. - html: 'Column[str]' = Column(Text, nullable=False) + html: Column[str] = Column(Text, nullable=False) #: null if not sent yet, otherwise the date this newsletter was first sent - sent: 'Column[datetime | None]' = Column(UTCDateTime, nullable=True) + sent: Column[datetime | None] = Column(UTCDateTime, nullable=True) #: time the newsletter is scheduled to be sent (in UTC) - scheduled: 'Column[datetime | None]' = Column(UTCDateTime, nullable=True) + scheduled: Column[datetime | None] = Column(UTCDateTime, nullable=True) #: the recipients of this newsletter, meant in part as a tracking feature #: to answer the question "who got which newsletters?" - for this to work #: the user of onegov.newsletter has to make sure that sent out #: newsletters can't have actual recipients removed from them. #: onegov.newsletter does not make any guarantees here - recipients: 'relationship[list[Recipient]]' = relationship( + recipients: relationship[list[Recipient]] = relationship( 'Recipient', secondary=newsletter_recipients, back_populates='newsletters') @property - def open_recipients(self) -> tuple['Recipient', ...]: + def open_recipients(self) -> tuple[Recipient, ...]: received = select([newsletter_recipients.c.recipient_id]).where( newsletter_recipients.c.newsletter_id == self.name) @@ -129,14 +131,14 @@ class Recipient(Base, TimestampMixin, ContentMixin): __tablename__ = 'recipients' #: the id of the recipient, used in the url - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the email address of the recipient, unique per group - address: 'Column[str]' = Column(Text, nullable=False) + address: Column[str] = Column(Text, nullable=False) @validates('address') def validate_address(self, key: str, address: str) -> str: @@ -144,21 +146,21 @@ def validate_address(self, key: str, address: str) -> str: return address #: the recipient group, a freely choosable string - may be null - group: 'Column[str | None]' = Column(Text, nullable=True) + group: Column[str | None] = Column(Text, nullable=True) #: the newsletters that this recipient received - newsletters: 'relationship[list[Newsletter]]' = relationship( + newsletters: relationship[list[Newsletter]] = relationship( 'Newsletter', secondary=newsletter_recipients, back_populates='recipients') #: this token is used for confirm and unsubscribe - token: 'Column[str]' = Column(Text, nullable=False, default=random_token) + token: Column[str] = Column(Text, nullable=False, default=random_token) #: when recipients are added, they are unconfirmed. At this point they get #: one e-mail with a confirmation link. If they ignore said e-mail they #: should not get another one. - confirmed: 'Column[bool]' = Column(Boolean, nullable=False, default=False) + confirmed: Column[bool] = Column(Boolean, nullable=False, default=False) #: subscribed newsletter categories. For legacy reasons, no selection # means all topics are subscribed to. @@ -178,7 +180,7 @@ def __table_args__(cls) -> tuple[Index, ...]: ) @property - def subscription(self) -> 'Subscription': + def subscription(self) -> Subscription: return Subscription(self, self.token) @@ -190,7 +192,7 @@ def __init__(self, recipient: Recipient, token: str): self.token = token @property - def recipient_id(self) -> 'uuid.UUID': + def recipient_id(self) -> uuid.UUID: # even though this seems redundant, we need this property # for morepath, so it can match it to the path variable return self.recipient.id diff --git a/src/onegov/newsletter/upgrade.py b/src/onegov/newsletter/upgrade.py index e7126cfdd5..aa5f7e8291 100644 --- a/src/onegov/newsletter/upgrade.py +++ b/src/onegov/newsletter/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + from onegov.core.upgrade import upgrade_task from onegov.core.orm.types import UTCDateTime, JSON from sqlalchemy import Column @@ -13,14 +15,14 @@ @upgrade_task('Add scheduled column') -def add_scheduled_column(context: 'UpgradeContext') -> None: +def add_scheduled_column(context: UpgradeContext) -> None: context.operations.add_column('newsletters', Column( 'scheduled', UTCDateTime, nullable=True )) @upgrade_task('Add content and meta columns') -def add_content_column(context: 'UpgradeContext') -> None: +def add_content_column(context: UpgradeContext) -> None: if not context.has_column('recipients', 'content'): context.operations.add_column('recipients', Column('content', JSON())) if not context.has_column('recipients', 'meta'): diff --git a/src/onegov/notice/__init__.py b/src/onegov/notice/__init__.py index 2608c00327..900a2bab15 100644 --- a/src/onegov/notice/__init__.py +++ b/src/onegov/notice/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.notice.models import OfficialNotice from onegov.notice.collections import OfficialNoticeCollection diff --git a/src/onegov/notice/collections.py b/src/onegov/notice/collections.py index 171b453415..ac75f243ad 100644 --- a/src/onegov/notice/collections.py +++ b/src/onegov/notice/collections.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.collection import Pagination from onegov.core.utils import increment_name from onegov.core.utils import normalize_for_url @@ -37,7 +39,7 @@ def get_unique_notice_name( name: str, - session: 'Session', + session: Session, model_class: type[OfficialNotice] ) -> str: """ Create a unique, URL-friendly name. """ @@ -60,17 +62,17 @@ class OfficialNoticeCollection(Pagination[_N]): def __init__( self, - session: 'Session', + session: Session, page: int = 0, - state: 'NoticeState | None' = None, + state: NoticeState | None = None, term: str | None = None, order: str | None = None, direction: Literal['asc', 'desc'] | None = None, - issues: 'Collection[str] | None ' = None, - categories: 'Collection[str] | None' = None, - organizations: 'Collection[str] | None' = None, - user_ids: list['UUID'] | None = None, - group_ids: list['UUID'] | None = None + issues: Collection[str] | None = None, + categories: Collection[str] | None = None, + organizations: Collection[str] | None = None, + user_ids: list[UUID] | None = None, + group_ids: list[UUID] | None = None ): super().__init__(page) self.session = session @@ -102,14 +104,14 @@ def __eq__(self, other: object) -> bool: and self.group_ids == other.group_ids ) - def subset(self) -> 'Query[_N]': + def subset(self) -> Query[_N]: return self.query() @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Self': + def page_by_index(self, index: int) -> Self: return self.__class__( self.session, page=index, @@ -124,7 +126,7 @@ def page_by_index(self, index: int) -> 'Self': group_ids=self.group_ids ) - def for_state(self, state: 'NoticeState') -> 'Self': + def for_state(self, state: NoticeState) -> Self: """ Returns a new instance of the collection with the given state. """ return self.__class__( @@ -140,7 +142,7 @@ def for_state(self, state: 'NoticeState') -> 'Self': group_ids=self.group_ids ) - def for_term(self, term: str | None) -> 'Self': + def for_term(self, term: str | None) -> Self: """ Returns a new instance of the collection with the given term. """ return self.__class__( @@ -160,7 +162,7 @@ def for_order( self, order: str, direction: Literal['asc', 'desc'] | None = None - ) -> 'Self': + ) -> Self: """ Returns a new instance of the collection with the given ordering. Inverts the direction if the new ordering is the same as the old one and an explicit ordering is not defined. @@ -188,8 +190,8 @@ def for_order( def for_organizations( self, - organizations: 'Collection[str] | None' - ) -> 'Self': + organizations: Collection[str] | None + ) -> Self: """ Returns a new instance of the collection with the given organizations. @@ -208,7 +210,7 @@ def for_organizations( group_ids=self.group_ids ) - def for_categories(self, categories: 'Collection[str] | None') -> 'Self': + def for_categories(self, categories: Collection[str] | None) -> Self: """ Returns a new instance of the collection with the given categories. """ @@ -231,7 +233,7 @@ def model_class(self) -> type[_N]: return OfficialNotice # type:ignore[return-value] @property - def term_columns(self) -> list['_StrColumnLike']: + def term_columns(self) -> list[_StrColumnLike]: """ The columns used for full text search. """ return [ @@ -248,7 +250,7 @@ def term_columns(self) -> list['_StrColumnLike']: User.username ] - def filter_query(self, query: 'Query[_N]') -> 'Query[_N]': + def filter_query(self, query: Query[_N]) -> Query[_N]: """ Filters the given query by the state of the collection. """ if self.state: @@ -284,7 +286,7 @@ def filter_query(self, query: 'Query[_N]') -> 'Query[_N]': return query - def order_query(self, query: 'Query[_N]') -> 'Query[_N]': + def order_query(self, query: Query[_N]) -> Query[_N]: """ Orders the given query by the state of the collection. """ direction = desc if self.direction == 'desc' else asc @@ -303,7 +305,7 @@ def order_query(self, query: 'Query[_N]') -> 'Query[_N]': return query.order_by(None).order_by(direction(attribute)) - def query(self) -> 'Query[_N]': + def query(self) -> Query[_N]: """ Returns a filtered and sorted query. Filters by: @@ -383,7 +385,7 @@ def by_name(self, name: str) -> _N | None: query = query.filter(self.model_class.name == name) return query.first() - def by_id(self, id: 'UUID') -> _N | None: + def by_id(self, id: UUID) -> _N | None: """ Returns a notice by its id. """ query = self.session.query(self.model_class) diff --git a/src/onegov/notice/models.py b/src/onegov/notice/models.py index 7a1ebfbdda..12137cfae4 100644 --- a/src/onegov/notice/models.py +++ b/src/onegov/notice/models.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import Base from onegov.core.orm.mixins import ContentMixin from onegov.core.orm.mixins import TimestampMixin @@ -62,7 +64,7 @@ class OfficialNotice(Base, ContentMixin, TimestampMixin): #: subclasses of this class. See #: ``_. - type: 'Column[str]' = Column( + type: Column[str] = Column( Text, nullable=False, default=lambda: 'generic' @@ -74,7 +76,7 @@ class OfficialNotice(Base, ContentMixin, TimestampMixin): } #: The internal ID of the notice. - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 @@ -82,10 +84,10 @@ class OfficialNotice(Base, ContentMixin, TimestampMixin): #: A nice ID usable for the url, readable by humans. # FIXME: Should this be nullable=True? - name: 'Column[str | None]' = Column(Text) + name: Column[str | None] = Column(Text) #: The state of the notice. - state: 'Column[NoticeState]' = Column( + state: Column[NoticeState] = Column( Enum( # type:ignore[arg-type] 'drafted', 'submitted', @@ -100,26 +102,28 @@ class OfficialNotice(Base, ContentMixin, TimestampMixin): ) #: The title of the notice. - title: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) #: The text of the notice. - text: 'Column[Markup | None]' = Column(MarkupText, nullable=True) + text: Column[Markup | None] = Column(MarkupText, nullable=True) #: The author of the notice. - author_name: 'Column[str | None]' = Column(Text, nullable=True) + author_name: Column[str | None] = Column(Text, nullable=True) #: The place (part of the signature). - author_place: 'Column[str | None]' = Column(Text, nullable=True) + author_place: Column[str | None] = Column(Text, nullable=True) #: The date (part of the signature) - author_date: 'Column[datetime | None]' = Column(UTCDateTime, nullable=True) + author_date: Column[datetime | None] = Column(UTCDateTime, nullable=True) #: A note to the notice. - note: 'Column[str | None]' = Column(Text, nullable=True) + note: Column[str | None] = Column(Text, nullable=True) #: The issues this notice appears in. - _issues: 'Column[dict[str, str | None]]' = Column( # type:ignore - MutableDict.as_mutable(HSTORE), name='issues', nullable=True + _issues: Column[dict[str, str | None]] = Column( # type:ignore + MutableDict.as_mutable(HSTORE), # type:ignore[no-untyped-call] + name='issues', + nullable=True ) @property @@ -132,17 +136,17 @@ def issues(self) -> dict[str, str | None]: # to just always pass in a dict. Once everything is fully type # checked we can simplify the implementation. @issues.setter - def issues(self, value: 'dict[str, str | None] | Iterable[str]') -> None: + def issues(self, value: dict[str, str | None] | Iterable[str]) -> None: if isinstance(value, dict): self._issues = value else: self._issues = dict.fromkeys(value, None) #: The date of the first issue of the notice. - first_issue: 'Column[datetime | None]' = Column(UTCDateTime, nullable=True) + first_issue: Column[datetime | None] = Column(UTCDateTime, nullable=True) #: The expiry date of the notice - expiry_date: 'Column[datetime | None]' = Column(UTCDateTime, nullable=True) + expiry_date: Column[datetime | None] = Column(UTCDateTime, nullable=True) @property def expired(self) -> bool: @@ -153,8 +157,10 @@ def expired(self) -> bool: return False #: The categories of this notice. - _categories: 'Column[dict[str, str | None]]' = Column( # type:ignore - MutableDict.as_mutable(HSTORE), name='categories', nullable=True + _categories: Column[dict[str, str | None]] = Column( # type:ignore + MutableDict.as_mutable(HSTORE), # type:ignore[no-untyped-call] + name='categories', + nullable=True ) @property @@ -165,7 +171,7 @@ def categories(self) -> dict[str, str | None]: @categories.setter def categories( self, - value: 'dict[str, str | None] | Iterable[str]' + value: dict[str, str | None] | Iterable[str] ) -> None: if isinstance(value, dict): self._categories = value @@ -173,15 +179,17 @@ def categories( self._categories = dict.fromkeys(value, None) #: The category of the notice. - category: 'Column[str | None]' = Column(Text, nullable=True) + category: Column[str | None] = Column(Text, nullable=True) #: The organization this notice belongs to. - organization: 'Column[str | None]' = Column(Text, nullable=True) + organization: Column[str | None] = Column(Text, nullable=True) #: The organizations of this notice. - _organizations: 'Column[dict[str, str | None] | None]' + _organizations: Column[dict[str, str | None] | None] _organizations = Column( # type:ignore[call-overload] - MutableDict.as_mutable(HSTORE), name='organizations', nullable=True + MutableDict.as_mutable(HSTORE), # type:ignore[no-untyped-call] + name='organizations', + nullable=True ) @property @@ -192,7 +200,7 @@ def organizations(self) -> dict[str, str | None]: @organizations.setter def organizations( self, - value: 'dict[str, str | None] | Iterable[str]' + value: dict[str, str | None] | Iterable[str] ) -> None: if isinstance(value, dict): self._organizations = value @@ -200,27 +208,27 @@ def organizations( self._organizations = dict.fromkeys(value, None) #: The user that owns this notice. - user_id: 'Column[uuid.UUID | None]' = Column( + user_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey(User.id), nullable=True ) - user: 'relationship[User | None]' = relationship( + user: relationship[User | None] = relationship( User, backref=backref('official_notices', lazy='select') ) #: The group that owns this notice. - group_id: 'Column[uuid.UUID | None]' = Column( + group_id: Column[uuid.UUID | None] = Column( UUID, # type:ignore[arg-type] ForeignKey(UserGroup.id), nullable=True ) - group: 'relationship[UserGroup | None]' = relationship( + group: relationship[UserGroup | None] = relationship( UserGroup, backref=backref('official_notices', lazy='select') ) #: The source from where this notice has been imported. - source: 'Column[str | None]' = Column(Text, nullable=True) + source: Column[str | None] = Column(Text, nullable=True) def submit(self) -> None: """ Submit a drafted notice. """ diff --git a/src/onegov/notice/upgrade.py b/src/onegov/notice/upgrade.py index 36271a14b2..7ed19d5ed8 100644 --- a/src/onegov/notice/upgrade.py +++ b/src/onegov/notice/upgrade.py @@ -2,6 +2,8 @@ upgraded on the server. See :class:`onegov.core.upgrade.upgrade_task`. """ +from __future__ import annotations + from onegov.core.orm.types import UTCDateTime from onegov.core.upgrade import upgrade_task from sqlalchemy import Column @@ -16,7 +18,7 @@ @upgrade_task('Add categories column to official notices') -def add_categories(context: 'UpgradeContext') -> None: +def add_categories(context: UpgradeContext) -> None: if not context.has_column('official_notices', 'categories'): context.operations.add_column( 'official_notices', @@ -25,7 +27,7 @@ def add_categories(context: 'UpgradeContext') -> None: @upgrade_task('Add organizations column to official notices') -def add_organizations(context: 'UpgradeContext') -> None: +def add_organizations(context: UpgradeContext) -> None: if not context.has_column('official_notices', 'organizations'): context.operations.add_column( 'official_notices', @@ -34,7 +36,7 @@ def add_organizations(context: 'UpgradeContext') -> None: @upgrade_task('Add author fields to official notices') -def add_author_fields(context: 'UpgradeContext') -> None: +def add_author_fields(context: UpgradeContext) -> None: if not context.has_column('official_notices', 'author_name'): context.operations.add_column( 'official_notices', @@ -53,7 +55,7 @@ def add_author_fields(context: 'UpgradeContext') -> None: @upgrade_task('Add an imported state to official notices') -def add_imported_state_to_notices(context: 'UpgradeContext') -> None: +def add_imported_state_to_notices(context: UpgradeContext) -> None: old = ['drafted', 'submitted', 'published', 'rejected', 'accepted'] new = [*old, 'imported'] old_type = Enum(*old, name='official_notice_state') @@ -75,7 +77,7 @@ def add_imported_state_to_notices(context: 'UpgradeContext') -> None: @upgrade_task('Add a souurce column to official notices') -def add_source_column_to_notices(context: 'UpgradeContext') -> None: +def add_source_column_to_notices(context: UpgradeContext) -> None: if not context.has_column('official_notices', 'source'): context.operations.add_column( 'official_notices', @@ -84,7 +86,7 @@ def add_source_column_to_notices(context: 'UpgradeContext') -> None: @upgrade_task('Add an expiry date column to official notices') -def add_expiry_date_column_to_notices(context: 'UpgradeContext') -> None: +def add_expiry_date_column_to_notices(context: UpgradeContext) -> None: if not context.has_column('official_notices', 'expiry_date'): context.operations.add_column( 'official_notices', @@ -93,7 +95,7 @@ def add_expiry_date_column_to_notices(context: 'UpgradeContext') -> None: @upgrade_task('Add note column to official notices') -def add_note_to_notices(context: 'UpgradeContext') -> None: +def add_note_to_notices(context: UpgradeContext) -> None: if not context.has_column('official_notices', 'note'): context.operations.add_column( 'official_notices', @@ -103,7 +105,7 @@ def add_note_to_notices(context: 'UpgradeContext') -> None: @upgrade_task('Make official notice polymorphic type non-nullable') def make_official_notice_polymorphic_type_non_nullable( - context: 'UpgradeContext' + context: UpgradeContext ) -> None: if context.has_table('official_notices'): context.operations.execute(""" diff --git a/src/onegov/onboarding/__init__.py b/src/onegov/onboarding/__init__.py index b93bac3952..2b4d472911 100644 --- a/src/onegov/onboarding/__init__.py +++ b/src/onegov/onboarding/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.onboarding') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/onboarding/app.py b/src/onegov/onboarding/app.py index a460033181..12b995d46b 100644 --- a/src/onegov/onboarding/app.py +++ b/src/onegov/onboarding/app.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core import Framework, utils from onegov.file import DepotApp from onegov.onboarding.theme import OnboardingTheme @@ -73,7 +75,7 @@ def get_webasset_output() -> str: @OnboardingApp.webasset('common') -def get_common_asset() -> 'Iterator[str]': +def get_common_asset() -> Iterator[str]: yield 'modernizr.js' yield 'jquery.js' yield 'placeholder.js' diff --git a/src/onegov/onboarding/errors.py b/src/onegov/onboarding/errors.py index e463807419..0175d6f680 100644 --- a/src/onegov/onboarding/errors.py +++ b/src/onegov/onboarding/errors.py @@ -1,2 +1,5 @@ +from __future__ import annotations + + class AlreadyExistsError(Exception): """ Raised if a product of an onboarding process exists already. """ diff --git a/src/onegov/onboarding/forms/__init__.py b/src/onegov/onboarding/forms/__init__.py index 0e6579eb3e..6f26a5939a 100644 --- a/src/onegov/onboarding/forms/__init__.py +++ b/src/onegov/onboarding/forms/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.onboarding.forms.town import FinishForm, TownForm __all__ = ['FinishForm', 'TownForm'] diff --git a/src/onegov/onboarding/forms/town.py b/src/onegov/onboarding/forms/town.py index baf9726012..67c02c201b 100644 --- a/src/onegov/onboarding/forms/town.py +++ b/src/onegov/onboarding/forms/town.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re from onegov.form import Form diff --git a/src/onegov/onboarding/i18n.py b/src/onegov/onboarding/i18n.py index 79836bf42b..a5904ee858 100644 --- a/src/onegov/onboarding/i18n.py +++ b/src/onegov/onboarding/i18n.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.i18n.translation_string import TranslationStringFactory _ = TranslationStringFactory('onegov.onboarding') diff --git a/src/onegov/onboarding/layout.py b/src/onegov/onboarding/layout.py index 1232384725..0780812edc 100644 --- a/src/onegov/onboarding/layout.py +++ b/src/onegov/onboarding/layout.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.layout import ChameleonLayout from onegov.core.static import StaticFile @@ -12,7 +14,7 @@ class Layout(ChameleonLayout): - def __init__(self, model: Any, request: 'CoreRequest'): + def __init__(self, model: Any, request: CoreRequest): super().__init__(model=model, request=request) self.request.include('common') @@ -42,9 +44,9 @@ class DefaultLayout(Layout): class MailLayout(Layout): @cached_property - def base(self) -> 'PageTemplateFile': + def base(self) -> PageTemplateFile: return self.template_loader['mail_layout.pt'] @cached_property - def macros(self) -> 'MacrosLookup': + def macros(self) -> MacrosLookup: raise NotImplementedError diff --git a/src/onegov/onboarding/models/__init__.py b/src/onegov/onboarding/models/__init__.py index 3532b9076f..7d39886d1b 100644 --- a/src/onegov/onboarding/models/__init__.py +++ b/src/onegov/onboarding/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.onboarding.models.assistant import ( Assistant, DefaultAssistant, diff --git a/src/onegov/onboarding/models/assistant.py b/src/onegov/onboarding/models/assistant.py index 7ede8dfbc2..16ffa2d71e 100644 --- a/src/onegov/onboarding/models/assistant.py +++ b/src/onegov/onboarding/models/assistant.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import inspect import time @@ -20,7 +22,7 @@ class Assistant: """ Describes an assistant guiding a user through onboarding. """ - def __init__(self, app: 'OnboardingApp', current_step_number: int = 1): + def __init__(self, app: OnboardingApp, current_step_number: int = 1): self.app = app @@ -39,7 +41,7 @@ def __init__(self, app: 'OnboardingApp', current_step_number: int = 1): self.current_step_number = current_step_number @property - def current_step(self) -> 'Step': + def current_step(self) -> Step: return self.steps[self.current_step_number - 1] @property @@ -54,31 +56,31 @@ def is_first_step(self) -> bool: def is_last_step(self) -> bool: return self.current_step_number == len(self.steps) - def for_next_step(self) -> 'Self': + def for_next_step(self) -> Self: assert not self.is_last_step return self.__class__(self.app, self.current_step_number + 1) - def for_prev_step(self) -> 'Self': + def for_prev_step(self) -> Self: assert not self.is_first_step return self.__class__(self.app, self.current_step_number - 1) - def for_first_step(self) -> 'Self': + def for_first_step(self) -> Self: return self.__class__(self.app, 1) @overload @classmethod - def step(cls, form: None = None) -> 'Callable[[_ViewF], _ViewF]': ... + def step(cls, form: None = None) -> Callable[[_ViewF], _ViewF]: ... @overload @classmethod def step( cls, - form: type['_FormT'] - ) -> 'Callable[[_FormView[_FormT, _T]], _FormView[_FormT, _T]]': ... + form: type[_FormT] + ) -> Callable[[_FormView[_FormT, _T]], _FormView[_FormT, _T]]: ... @classmethod - def step(cls, form: type['Form'] | None = None) -> 'Callable[[_F], _F]': - def decorator(fn: '_F') -> '_F': + def step(cls, form: type[Form] | None = None) -> Callable[[_F], _F]: + def decorator(fn: _F) -> _F: fn.is_step = True # type:ignore[attr-defined] # FIXME: monotonic may be more reliable fn.order = time.process_time() # type:ignore[attr-defined] @@ -95,7 +97,7 @@ class Step: @overload def __init__( self, - view_handler: 'Callable[[CoreRequest], Any]', + view_handler: Callable[[CoreRequest], Any], order: float, form: None ): ... @@ -103,25 +105,25 @@ def __init__( @overload def __init__( self, - view_handler: 'Callable[[CoreRequest, Form], Any]', + view_handler: Callable[[CoreRequest, Form], Any], order: float, - form: 'Form' + form: Form ): ... def __init__( self, - view_handler: 'Callable[..., Any]', + view_handler: Callable[..., Any], order: float, - form: 'Form | None' + form: Form | None ): self.view_handler = view_handler self.order = order self.form = form - def __lt__(self, other: 'Step') -> bool: + def __lt__(self, other: Step) -> bool: return self.order < other.order - def handle_view(self, request: 'CoreRequest', form: 'Form | None') -> Any: + def handle_view(self, request: CoreRequest, form: Form | None) -> Any: if form is None: return self.view_handler(request) else: diff --git a/src/onegov/onboarding/models/town_assistant.py b/src/onegov/onboarding/models/town_assistant.py index 98971182b3..3796965b1f 100644 --- a/src/onegov/onboarding/models/town_assistant.py +++ b/src/onegov/onboarding/models/town_assistant.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import morepath import re @@ -30,9 +32,9 @@ class TownAssistant(Assistant): @Assistant.step(form=TownForm) def first_step( self, - request: 'CoreRequest', + request: CoreRequest, form: TownForm - ) -> 'RenderData | Response': + ) -> RenderData | Response: if form.submitted(request): request.browser_session['name'] = form.name.data @@ -66,9 +68,9 @@ def first_step( @Assistant.step(form=FinishForm) def last_step( self, - request: 'CoreRequest', + request: CoreRequest, form: FinishForm - ) -> 'RenderData | Response': + ) -> RenderData | Response: for key in ('name', 'user', 'color'): if not request.browser_session.has(key): @@ -164,8 +166,8 @@ def add_town( name: str, user: str, color: str, - request: 'CoreRequest' - ) -> 'RenderData': + request: CoreRequest + ) -> RenderData: current_schema = self.app.session_manager.current_schema assert current_schema is not None diff --git a/src/onegov/onboarding/path.py b/src/onegov/onboarding/path.py index c647e0c0ed..f290043ce6 100644 --- a/src/onegov/onboarding/path.py +++ b/src/onegov/onboarding/path.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.onboarding import OnboardingApp from onegov.onboarding.models import DefaultAssistant, TownAssistant diff --git a/src/onegov/onboarding/theme/__init__.py b/src/onegov/onboarding/theme/__init__.py index 728c042393..03e029c4b1 100644 --- a/src/onegov/onboarding/theme/__init__.py +++ b/src/onegov/onboarding/theme/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.onboarding.theme.onboarding_theme import OnboardingTheme __all__ = ('OnboardingTheme',) diff --git a/src/onegov/onboarding/theme/onboarding_theme.py b/src/onegov/onboarding/theme/onboarding_theme.py index 291db2cdac..1150b66c27 100644 --- a/src/onegov/onboarding/theme/onboarding_theme.py +++ b/src/onegov/onboarding/theme/onboarding_theme.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from onegov.foundation import BaseTheme from onegov.core.utils import module_path diff --git a/src/onegov/onboarding/views/step.py b/src/onegov/onboarding/views/step.py index 4d7a7b76d5..af1696ef69 100644 --- a/src/onegov/onboarding/views/step.py +++ b/src/onegov/onboarding/views/step.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import morepath from onegov.core.security import Public @@ -19,8 +21,8 @@ @OnboardingApp.view(model=DefaultAssistant, permission=Public) def view_default_assistant( self: DefaultAssistant, - request: 'CoreRequest' -) -> 'Response': + request: CoreRequest +) -> Response: return morepath.redirect(request.link(self.assistant)) @@ -32,9 +34,9 @@ def view_default_assistant( ) def view_assistant( self: Assistant, - request: 'CoreRequest', - form: 'Form | None' -) -> 'RenderData | Response': + request: CoreRequest, + form: Form | None +) -> RenderData | Response: # usually this is morepath's job, but we're doing some funny things here ;) if form is None and request.method == 'POST': diff --git a/src/onegov/org/__init__.py b/src/onegov/org/__init__.py index d068016112..9317dcc79c 100644 --- a/src/onegov/org/__init__.py +++ b/src/onegov/org/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import logging log = logging.getLogger('onegov.org') log.addHandler(logging.NullHandler()) diff --git a/src/onegov/org/app.py b/src/onegov/org/app.py index e713c9ce39..4033bf6f0b 100644 --- a/src/onegov/org/app.py +++ b/src/onegov/org/app.py @@ -1,4 +1,5 @@ """ Contains the base application used by other applications. """ +from __future__ import annotations import re import yaml @@ -194,7 +195,7 @@ def homepage_template(self) -> PageTemplate: return PageTemplate('') @orm_cached(policy='on-table-change:tickets') - def ticket_count(self) -> 'TicketCount': + def ticket_count(self) -> TicketCount: return TicketCollection(self.session()).get_count() @orm_cached(policy='on-table-change:ticket_permissions') @@ -218,15 +219,15 @@ def prepare_email( self, reply_to: Address | str | None = None, category: Literal['marketing', 'transactional'] = 'marketing', - receivers: 'SequenceOrScalar[Address | str]' = (), - cc: 'SequenceOrScalar[Address | str]' = (), - bcc: 'SequenceOrScalar[Address | str]' = (), + receivers: SequenceOrScalar[Address | str] = (), + cc: SequenceOrScalar[Address | str] = (), + bcc: SequenceOrScalar[Address | str] = (), subject: str | None = None, content: str | None = None, - attachments: 'Iterable[Attachment | StrPath]' = (), + attachments: Iterable[Attachment | StrPath] = (), headers: dict[str, str] | None = None, plaintext: str | None = None - ) -> 'EmailJsonDict': + ) -> EmailJsonDict: """ Wraps :meth:`onegov.core.framework.Framework.prepare_email`, setting the reply_to address by using the reply address from the organisation settings. @@ -351,7 +352,7 @@ def checkout_button( self, button_label: str, title: str, - price: 'Price | None', + price: Price | None, email: str, locale: str ) -> str | None: @@ -385,7 +386,7 @@ def checkout_button( def redirect_after_login( self, - identity: 'Identity | NoIdentity', + identity: Identity | NoIdentity, request: OrgRequest, # type:ignore[override] default: str ) -> str | None: @@ -442,9 +443,9 @@ def get_i18n_default_locale() -> str: @OrgApp.setting(section='i18n', name='locale_negotiator') def get_locale_negotiator( -) -> 'Callable[[Sequence[str], OrgRequest], str | None]': +) -> Callable[[Sequence[str], OrgRequest], str | None]: def locale_negotiator( - locales: 'Sequence[str]', + locales: Sequence[str], request: OrgRequest ) -> str | None: @@ -476,7 +477,7 @@ def get_theme() -> OrgTheme: @OrgApp.setting(section='content_security_policy', name='default') -def org_content_security_policy() -> 'ContentSecurityPolicy': +def org_content_security_policy() -> ContentSecurityPolicy: policy = default_content_security_policy() policy.child_src.add(SELF) @@ -509,17 +510,17 @@ def org_content_security_policy() -> 'ContentSecurityPolicy': @OrgApp.setting(section='org', name='create_new_organisation') def get_create_new_organisation_factory( -) -> 'Callable[[OrgApp, str], Organisation]': +) -> Callable[[OrgApp, str], Organisation]: return create_new_organisation @OrgApp.setting(section='org', name='status_mail_roles') -def get_status_mail_roles() -> 'Collection[str]': +def get_status_mail_roles() -> Collection[str]: return ('admin', 'editor') @OrgApp.setting(section='org', name='ticket_manager_roles') -def get_ticket_manager_roles() -> 'Collection[str]': +def get_ticket_manager_roles() -> Collection[str]: return ('admin', 'editor') @@ -530,7 +531,7 @@ def get_require_complete_userprofile() -> bool: @OrgApp.setting(section='org', name='is_complete_userprofile') def get_is_complete_userprofile_handler( -) -> 'Callable[[OrgRequest, str], bool]': +) -> Callable[[OrgRequest, str], bool]: def is_complete_userprofile(request: OrgRequest, username: str) -> bool: return True @@ -549,7 +550,7 @@ def get_default_event_search_widget() -> None: @OrgApp.setting(section='org', name='public_ticket_messages') -def get_public_ticket_messages() -> 'Collection[str]': +def get_public_ticket_messages() -> Collection[str]: """ Returns a list of message types which are availble on the ticket status page, visible to anyone that knows the unguessable url. @@ -569,15 +570,15 @@ def get_public_ticket_messages() -> 'Collection[str]': @OrgApp.setting(section='org', name='disabled_extensions') -def get_disabled_extensions() -> 'Collection[str]': +def get_disabled_extensions() -> Collection[str]: return () @OrgApp.tween_factory(under=content_security_policy_tween_factory) def enable_iframes_tween_factory( app: OrgApp, - handler: 'Callable[[OrgRequest], Response]' -) -> 'Callable[[OrgRequest], Response]': + handler: Callable[[OrgRequest], Response] +) -> Callable[[OrgRequest], Response]: no_iframe_paths = ( r'/auth/.*', @@ -598,7 +599,7 @@ def enable_iframes_tween_factory( def enable_iframes_tween( request: OrgRequest - ) -> 'Response': + ) -> Response: """ Enables iframes. """ result = handler(request) @@ -635,13 +636,13 @@ def get_webasset_output() -> str: @OrgApp.webasset('sortable') -def get_sortable_asset() -> 'Iterator[str]': +def get_sortable_asset() -> Iterator[str]: yield 'sortable.js' yield 'sortable_custom.js' @OrgApp.webasset('fullcalendar') -def get_fullcalendar_asset() -> 'Iterator[str]': +def get_fullcalendar_asset() -> Iterator[str]: yield 'fullcalendar.css' yield 'fullcalendar.js' yield 'fullcalendar.de.js' @@ -651,13 +652,13 @@ def get_fullcalendar_asset() -> 'Iterator[str]': @OrgApp.webasset('reservationlist') -def get_reservation_list_asset() -> 'Iterator[str]': +def get_reservation_list_asset() -> Iterator[str]: yield 'reservationlist.jsx' yield 'reservationlist_custom.js' @OrgApp.webasset('code_editor') -def get_code_editor_asset() -> 'Iterator[str]': +def get_code_editor_asset() -> Iterator[str]: yield 'ace.js' yield 'ace-mode-form.js' yield 'ace-mode-markdown.js' @@ -669,7 +670,7 @@ def get_code_editor_asset() -> 'Iterator[str]': @OrgApp.webasset('editor') -def get_editor_asset() -> 'Iterator[str]': +def get_editor_asset() -> Iterator[str]: yield 'bufferbuttons.js' yield 'definedlinks.js' yield 'filemanager.js' @@ -683,35 +684,35 @@ def get_editor_asset() -> 'Iterator[str]': @OrgApp.webasset('timeline') -def get_timeline_asset() -> 'Iterator[str]': +def get_timeline_asset() -> Iterator[str]: yield 'timeline.jsx' # do NOT minify the redactor, or the copyright notice goes away, which # is something we are not allowed to do per our license @OrgApp.webasset('redactor', filters={'js': None}) -def get_redactor_asset() -> 'Iterator[str]': +def get_redactor_asset() -> Iterator[str]: yield 'redactor.js' yield 'redactor.css' @OrgApp.webasset('upload') -def get_upload_asset() -> 'Iterator[str]': +def get_upload_asset() -> Iterator[str]: yield 'upload.js' @OrgApp.webasset('editalttext') -def get_editalttext_asset() -> 'Iterator[str]': +def get_editalttext_asset() -> Iterator[str]: yield 'editalttext.js' @OrgApp.webasset('prompt') -def get_prompt() -> 'Iterator[str]': +def get_prompt() -> Iterator[str]: yield 'prompt.jsx' @OrgApp.webasset('photoswipe') -def get_photoswipe_asset() -> 'Iterator[str]': +def get_photoswipe_asset() -> Iterator[str]: yield 'photoswipe.css' yield 'photoswipe-skin.css' yield 'photoswipe.js' @@ -720,25 +721,25 @@ def get_photoswipe_asset() -> 'Iterator[str]': @OrgApp.webasset('tags-input') -def get_tags_input() -> 'Iterator[str]': +def get_tags_input() -> Iterator[str]: yield 'tags-input.js' yield 'tags-input-setup.js' @OrgApp.webasset('filedigest') -def get_filehash() -> 'Iterator[str]': +def get_filehash() -> Iterator[str]: yield 'asmcrypto-lite.js' yield 'filedigest.js' @OrgApp.webasset('monthly-view') -def get_monthly_view() -> 'Iterator[str]': +def get_monthly_view() -> Iterator[str]: yield 'daypicker.js' yield 'monthly-view.jsx' @OrgApp.webasset('common') -def get_common_asset() -> 'Iterator[str]': +def get_common_asset() -> Iterator[str]: yield 'global.js' yield 'polyfills.js' yield 'jquery.datetimepicker.css' @@ -786,28 +787,28 @@ def get_common_asset() -> 'Iterator[str]': @OrgApp.webasset('fontpreview') -def get_fontpreview_asset() -> 'Iterator[str]': +def get_fontpreview_asset() -> Iterator[str]: yield 'fontpreview.js' @OrgApp.webasset('scroll-to-username') -def get_scroll_to_username_asset() -> 'Iterator[str]': +def get_scroll_to_username_asset() -> Iterator[str]: yield 'scroll_to_username.js' @OrgApp.webasset('all_blank') -def get_all_blank_asset() -> 'Iterator[str]': +def get_all_blank_asset() -> Iterator[str]: yield 'all_blank.js' @OrgApp.webasset('people-select') -def people_select_asset() -> 'Iterator[str]': +def people_select_asset() -> Iterator[str]: yield 'people-select.js' def wrap_with_mtan_hook( - func: 'Callable[[OrgApp, Any, OrgRequest], Any]' -) -> 'Callable[[OrgApp, Any, OrgRequest], Any]': + func: Callable[[OrgApp, Any, OrgRequest], Any] +) -> Callable[[OrgApp, Any, OrgRequest], Any]: @wraps(func) def wrapped(self: OrgApp, obj: Any, request: OrgRequest) -> Any: @@ -842,13 +843,13 @@ def wrapped(self: OrgApp, obj: Any, request: OrgRequest) -> Any: class KeyLookupWithMTANHook: - def __init__(self, key_lookup: '_KeyLookup'): + def __init__(self, key_lookup: _KeyLookup): self.key_lookup = key_lookup def component( self, - key: 'Sequence[Any]' - ) -> 'Callable[..., Any] | None': + key: Sequence[Any] + ) -> Callable[..., Any] | None: result = self.key_lookup.component(key) if result is None: @@ -857,8 +858,8 @@ def component( def fallback( self, - key: 'Sequence[Any]' - ) -> 'Callable[..., Any] | None': + key: Sequence[Any] + ) -> Callable[..., Any] | None: result = self.key_lookup.fallback(key) if result is None: @@ -867,6 +868,6 @@ def fallback( def all( self, - key: 'Sequence[Any]' - ) -> 'Iterator[Callable[..., Any]]': + key: Sequence[Any] + ) -> Iterator[Callable[..., Any]]: return self.key_lookup.all(key) diff --git a/src/onegov/org/auth.py b/src/onegov/org/auth.py index 13de82439a..61c695ec27 100644 --- a/src/onegov/org/auth.py +++ b/src/onegov/org/auth.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import morepath from onegov.core.utils import relative_url @@ -27,13 +29,13 @@ class MTANAuth: """ - def __init__(self, app: 'OrgApp', to: str = '/'): + def __init__(self, app: OrgApp, to: str = '/'): self.app = app self.session = app.session() self.application_id = app.application_id self.to = relative_url(to) - def send_mtan(self, request: 'OrgRequest', number: str) -> 'Response': + def send_mtan(self, request: OrgRequest, number: str) -> Response: # we are already authenticated just redirect to the page we wanted if request.active_mtan_session: @@ -66,7 +68,7 @@ def send_mtan(self, request: 'OrgRequest', number: str) -> 'Response': def authenticate( self, - request: 'OrgRequest', + request: OrgRequest, tan: str, ) -> str | None: diff --git a/src/onegov/org/cli.py b/src/onegov/org/cli.py index e58ad7d859..f667110dfe 100644 --- a/src/onegov/org/cli.py +++ b/src/onegov/org/cli.py @@ -1,4 +1,6 @@ """ Provides commands used to initialize org websites. """ +from __future__ import annotations + import click import html import isodate @@ -70,10 +72,10 @@ ) @pass_group_context def add( - group_context: 'GroupContext', + group_context: GroupContext, name: str, locale: str -) -> 'Callable[[OrgRequest, OrgApp], None]': +) -> Callable[[OrgRequest, OrgApp], None]: """ Adds an org with the given name to the database. For example: .. code-block:: bash @@ -82,7 +84,7 @@ def add( """ - def add_org(request: 'OrgRequest', app: 'OrgApp') -> None: + def add_org(request: OrgRequest, app: OrgApp) -> None: if app.session().query(Organisation).first(): abort('{} already contains an organisation'.format( @@ -105,7 +107,7 @@ def import_digirez( accessdb: str, min_date: str, ignore_booking_conflicts: bool -) -> 'Callable[[OrgRequest, OrgApp], None]': +) -> Callable[[OrgRequest, OrgApp], None]: """ Imports a Digirez reservation database into onegov.org. Example: @@ -159,8 +161,8 @@ def import_digirez( } def get_formdata( - member: 'DefaultRow', - booking: 'DefaultRow' + member: DefaultRow, + booking: DefaultRow ) -> dict[str, Any]: einrichtungen = [] @@ -228,7 +230,7 @@ def unescape_dictionary(d: dict[str, Any]) -> dict[str, Any]: (re.compile(r'@pro-vitalis$'), '@pro-vitalis.ch') ) - def run_import(request: 'OrgRequest', app: 'OrgApp') -> None: + def run_import(request: OrgRequest, app: OrgApp) -> None: # create all resources first, fails if at least one exists already print('Creating resources') @@ -418,11 +420,11 @@ def run_import(request: 'OrgRequest', app: 'OrgApp') -> None: help='Do not write any changes into the database.') @pass_group_context def fix_tags( - group_context: 'GroupContext', + group_context: GroupContext, dry_run: bool -) -> 'Callable[[OrgRequest, OrgApp], None]': +) -> Callable[[OrgRequest, OrgApp], None]: - def fixes_german_tags_in_db(request: 'OrgRequest', app: 'OrgApp') -> None: + def fixes_german_tags_in_db(request: OrgRequest, app: OrgApp) -> None: session = request.session de_transl = app.translations.get('de_CH') @@ -431,7 +433,7 @@ def fixes_german_tags_in_db(request: 'OrgRequest', app: 'OrgApp') -> None: defined_tags = list(TAGS) defined_tag_ids = [str(s) for s in defined_tags] - def translate(text: 'TranslationString') -> str: + def translate(text: TranslationString) -> str: return text.interpolate(de_transl.gettext(text)) form_de_to_en = {translate(text): str(text) for text in defined_tags} @@ -496,7 +498,7 @@ def handle_occurrence_tags(occurrence: Event | Occurrence) -> None: return fixes_german_tags_in_db -def close_ticket(ticket: 'Ticket', user: User, request: 'OrgRequest') -> None: +def close_ticket(ticket: Ticket, user: User, request: OrgRequest) -> None: if ticket.state == 'open': ticket.accept_ticket(user) TicketMessage.create( @@ -525,15 +527,15 @@ def close_ticket(ticket: 'Ticket', user: User, request: 'OrgRequest') -> None: help='Only add event is they are published on remote') @click.option('--delete-orphaned-tickets', is_flag=True) def fetch( - group_context: 'GroupContext', - source: 'Sequence[str]', - tag: 'Sequence[str]', - location: 'Sequence[str]', + group_context: GroupContext, + source: Sequence[str], + tag: Sequence[str], + location: Sequence[str], create_tickets: bool, - state_transfers: 'Sequence[str]', + state_transfers: Sequence[str], published_only: bool, delete_orphaned_tickets: bool -) -> 'Callable[[OrgRequest, OrgApp], None]': +) -> Callable[[OrgRequest, OrgApp], None]: r""" Fetches events from other instances. Only fetches events from the same namespace which have not been imported @@ -578,7 +580,7 @@ def fetch( """ - def vector_add(a: 'Sequence[int]', b: 'Sequence[int]') -> list[int]: + def vector_add(a: Sequence[int], b: Sequence[int]) -> list[int]: return list(map(add_op, a, b)) if not len(source): @@ -594,9 +596,9 @@ def vector_add(a: 'Sequence[int]', b: 'Sequence[int]') -> list[int]: assert remote in valid_choices valid_state_transfers[local] = remote - def _fetch(request: 'OrgRequest', app: 'OrgApp') -> None: + def _fetch(request: OrgRequest, app: OrgApp) -> None: - def event_file(reference: 'UploadedFile') -> BytesIO: + def event_file(reference: UploadedFile) -> BytesIO: # XXX use a proper depot manager for this assert app.depot_storage_path is not None path = Path(app.depot_storage_path) / reference['path'] / 'file' @@ -637,9 +639,9 @@ def event_file(reference: 'UploadedFile') -> BytesIO: ) def remote_events( - query: 'Query[Event]' = query, + query: Query[Event] = query, key: str = key - ) -> 'Iterator[EventImportItem]': + ) -> Iterator[EventImportItem]: for event_ in query: event_._es_skip = True @@ -696,9 +698,9 @@ def remote_events( abort('Can not create tickets, no admin is registered') def ticket_for_event( - event_id: 'UUID', - local_session: 'Session' = local_session - ) -> 'Ticket | None': + event_id: UUID, + local_session: Session = local_session + ) -> Ticket | None: return TicketCollection(local_session).by_handler_id( event_id.hex) @@ -775,8 +777,8 @@ def ticket_for_event( @cli.command('fix-directory-files') @pass_group_context def fix_directory_files( - group_context: 'GroupContext' -) -> 'Callable[[OrgRequest, OrgApp], None]': + group_context: GroupContext +) -> Callable[[OrgRequest, OrgApp], None]: """ Not sure of this doubles the files, but actually the file reference remains, so it shouldn't @@ -785,7 +787,7 @@ def fix_directory_files( submissions are set correctly with type 'directory'. """ - def execute(request: 'OrgRequest', app: 'OrgApp') -> None: + def execute(request: OrgRequest, app: OrgApp) -> None: count = 0 for entry in request.session.query(DirectoryEntry).all(): for field in entry.directory.file_fields: @@ -817,14 +819,14 @@ def execute(request: 'OrgRequest', app: 'OrgApp') -> None: @cli.command('migrate-town', context_settings={'singular': True}) @pass_group_context def migrate_town( - group_context: 'GroupContext' -) -> 'Callable[[OrgRequest, OrgApp], None]': + group_context: GroupContext +) -> Callable[[OrgRequest, OrgApp], None]: """ Migrates the database from an old town to the new town like in the upgrades. """ - def migrate_to_new_town(request: 'OrgRequest', app: 'OrgApp') -> None: + def migrate_to_new_town(request: OrgRequest, app: OrgApp) -> None: context: UpgradeContext = Bunch(session=app.session()) # type:ignore migrate_theme_options(context) migrate_homepage_structure_for_town6(context) @@ -837,10 +839,10 @@ def migrate_to_new_town(request: 'OrgRequest', app: 'OrgApp') -> None: @click.argument('old-uri') @click.option('--dry-run', is_flag=True, default=False) def migrate_links_cli( - group_context: 'GroupContext', + group_context: GroupContext, old_uri: str, dry_run: bool -) -> 'Callable[[OrgRequest, OrgApp], None]': +) -> Callable[[OrgRequest, OrgApp], None]: """ Migrates url's in pages. Supports domains and full urls. Most of the urls are located in meta and content fields. """ @@ -849,7 +851,7 @@ def migrate_links_cli( click.secho('Domain must contain a dot') sys.exit(1) - def execute(request: 'OrgRequest', app: 'OrgApp') -> None: + def execute(request: OrgRequest, app: OrgApp) -> None: if old_uri.startswith('http'): new_uri = request.host_url else: @@ -875,12 +877,12 @@ def execute(request: 'OrgRequest', app: 'OrgApp') -> None: @cli.command(context_settings={'default_selector': '*'}) @pass_group_context def migrate_publications( - group_context: 'GroupContext', + group_context: GroupContext, dry_run: bool -) -> 'Callable[[OrgRequest, OrgApp], None]': +) -> Callable[[OrgRequest, OrgApp], None]: """ Marks signed files for publication. """ - def mark_as_published(request: 'OrgRequest', app: 'OrgApp') -> None: + def mark_as_published(request: OrgRequest, app: OrgApp) -> None: session = request.session files = session.query(File).filter_by(signed=True).all() for file in files: @@ -895,7 +897,7 @@ def mark_as_published(request: 'OrgRequest', app: 'OrgApp') -> None: @cli.command(name='delete-invisible-links') -def delete_invisible_links() -> 'Callable[[OrgRequest, OrgApp], None]': +def delete_invisible_links() -> Callable[[OrgRequest, OrgApp], None]: """ Deletes all the data associated with a period, including: Example: @@ -905,7 +907,7 @@ def delete_invisible_links() -> 'Callable[[OrgRequest, OrgApp], None]': """ - def delete_invisible_links(request: 'OrgRequest', app: 'OrgApp') -> None: + def delete_invisible_links(request: OrgRequest, app: OrgApp) -> None: session = request.session query = QueryChain( (session.query(Page), diff --git a/src/onegov/org/constants.py b/src/onegov/org/constants.py index b4eef93de2..70f1fdc164 100644 --- a/src/onegov/org/constants.py +++ b/src/onegov/org/constants.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.org import _ @@ -7,7 +9,7 @@ from onegov.ticket.collection import ExtendedTicketState -TICKET_STATES: dict['ExtendedTicketState', str] = { +TICKET_STATES: dict[ExtendedTicketState, str] = { 'open': _('Open'), 'pending': _('Pending'), 'closed': _('Closed'), @@ -15,7 +17,7 @@ 'all': _('All') } -PAYMENT_STATES: dict['PaymentState', str] = { +PAYMENT_STATES: dict[PaymentState, str] = { 'open': TICKET_STATES['open'], 'paid': _('Paid'), 'failed': _('Failed'), diff --git a/src/onegov/org/converters.py b/src/onegov/org/converters.py index 08c017ea0c..3ca206a63d 100644 --- a/src/onegov/org/converters.py +++ b/src/onegov/org/converters.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import morepath from collections import defaultdict @@ -14,7 +16,7 @@ def keywords(self) -> Mapping[str, Sequence[str]]: ... def keywords_encode( - keywords: 'HasKeywords | Mapping[str, Sequence[str]]' + keywords: HasKeywords | Mapping[str, Sequence[str]] ) -> str: """ Takes a dictionary of keywords and encodes them into a somewhat readable url query format. diff --git a/src/onegov/org/cronjobs.py b/src/onegov/org/cronjobs.py index 385421e47e..7be3f897d3 100644 --- a/src/onegov/org/cronjobs.py +++ b/src/onegov/org/cronjobs.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from babel.dates import get_month_names from datetime import datetime, timedelta @@ -67,7 +69,7 @@ @OrgApp.cronjob(hour='*', minute=0, timezone='UTC') -def hourly_maintenance_tasks(request: 'OrgRequest') -> None: +def hourly_maintenance_tasks(request: OrgRequest) -> None: publish_files(request) handle_publication_models(request) send_scheduled_newsletter(request) @@ -75,7 +77,7 @@ def hourly_maintenance_tasks(request: 'OrgRequest') -> None: delete_old_tan_accesses(request) -def send_scheduled_newsletter(request: 'OrgRequest') -> None: +def send_scheduled_newsletter(request: OrgRequest) -> None: newsletters = NewsletterCollection(request.session).query().filter(and_( Newsletter.scheduled != None, Newsletter.scheduled <= (utcnow() + timedelta(seconds=60)), @@ -86,11 +88,11 @@ def send_scheduled_newsletter(request: 'OrgRequest') -> None: newsletter.scheduled = None -def publish_files(request: 'OrgRequest') -> None: +def publish_files(request: OrgRequest) -> None: FileCollection(request.session).publish_files() -def handle_publication_models(request: 'OrgRequest') -> None: +def handle_publication_models(request: OrgRequest) -> None: """ Reindexes all recently published/unpublished objects in the elasticsearch database. @@ -106,9 +108,9 @@ def handle_publication_models(request: 'OrgRequest') -> None: return def publication_models( - base: type['Base'] + base: type[Base] # NOTE: This should be Iterator[type[Base & UTCPublicationMixin]] - ) -> 'Iterator[type[UTCPublicationMixin]]': + ) -> Iterator[type[UTCPublicationMixin]]: yield from find_models(base, lambda cls: issubclass( # type:ignore cls, UTCPublicationMixin) ) @@ -150,7 +152,7 @@ def publication_models( request.app.org.meta['hourly_maintenance_tasks_last_run'] = now -def delete_old_tans(request: 'OrgRequest') -> None: +def delete_old_tans(request: OrgRequest) -> None: """ Deletes TANs that are older than half a year. @@ -166,7 +168,7 @@ def delete_old_tans(request: 'OrgRequest') -> None: query.delete(synchronize_session=False) -def delete_old_tan_accesses(request: 'OrgRequest') -> None: +def delete_old_tan_accesses(request: OrgRequest) -> None: """ Deletes TAN accesses that are older than half a year. @@ -183,7 +185,7 @@ def delete_old_tan_accesses(request: 'OrgRequest') -> None: @OrgApp.cronjob(hour=23, minute=45, timezone='Europe/Zurich') -def process_resource_rules(request: 'OrgRequest') -> None: +def process_resource_rules(request: OrgRequest) -> None: resources = ResourceCollection(request.app.libres_context) for resource in resources.query(): @@ -191,7 +193,7 @@ def process_resource_rules(request: 'OrgRequest') -> None: def ticket_statistics_common_template_args( - request: 'OrgRequest', + request: OrgRequest, collection: TicketCollection ) -> dict[str, Any]: @@ -236,7 +238,7 @@ def ticket_statistics_users(app: OrgApp) -> list[User]: @OrgApp.cronjob(hour=8, minute=30, timezone='Europe/Zurich') -def send_daily_ticket_statistics(request: 'OrgRequest') -> None: +def send_daily_ticket_statistics(request: OrgRequest) -> None: today = to_timezone(utcnow(), 'Europe/Zurich') @@ -301,7 +303,7 @@ def send_daily_ticket_statistics(request: 'OrgRequest') -> None: @OrgApp.cronjob(hour=8, minute=45, timezone='Europe/Zurich') -def send_weekly_ticket_statistics(request: 'OrgRequest') -> None: +def send_weekly_ticket_statistics(request: OrgRequest) -> None: today = to_timezone(utcnow(), 'Europe/Zurich') @@ -362,7 +364,7 @@ def send_weekly_ticket_statistics(request: 'OrgRequest') -> None: @OrgApp.cronjob(hour=9, minute=0, timezone='Europe/Zurich') -def send_monthly_ticket_statistics(request: 'OrgRequest') -> None: +def send_monthly_ticket_statistics(request: OrgRequest) -> None: today = to_timezone(utcnow(), 'Europe/Zurich') @@ -427,7 +429,7 @@ def send_monthly_ticket_statistics(request: 'OrgRequest') -> None: @OrgApp.cronjob(hour=6, minute=5, timezone='Europe/Zurich') -def send_daily_resource_usage_overview(request: 'OrgRequest') -> None: +def send_daily_resource_usage_overview(request: OrgRequest) -> None: today = to_timezone(utcnow(), 'Europe/Zurich') weekday = WEEKDAYS[today.weekday()] @@ -483,7 +485,7 @@ def send_daily_resource_usage_overview(request: 'OrgRequest') -> None: ) @lru_cache(maxsize=128) - def form(definition: str) -> type['Form']: + def form(definition: str) -> type[Form]: return parse_form(definition) # get the reservations of this day @@ -555,7 +557,7 @@ def form(definition: str) -> type['Form']: @OrgApp.cronjob(hour='*', minute='*/30', timezone='UTC') -def end_chats_and_create_tickets(request: 'OrgRequest') -> None: +def end_chats_and_create_tickets(request: OrgRequest) -> None: half_hour_ago = utcnow() - timedelta(minutes=30) chats = ChatCollection(request.session).query().filter( @@ -586,7 +588,7 @@ def end_chats_and_create_tickets(request: 'OrgRequest') -> None: @OrgApp.cronjob(hour=4, minute=30, timezone='Europe/Zurich') -def archive_old_tickets(request: 'OrgRequest') -> None: +def archive_old_tickets(request: OrgRequest) -> None: archive_timespan = request.app.org.auto_archive_timespan session = request.session @@ -617,7 +619,7 @@ def archive_old_tickets(request: 'OrgRequest') -> None: @OrgApp.cronjob(hour=5, minute=30, timezone='Europe/Zurich') -def delete_old_tickets(request: 'OrgRequest') -> None: +def delete_old_tickets(request: OrgRequest) -> None: delete_timespan = request.app.org.auto_delete_timespan session = request.session @@ -636,7 +638,7 @@ def delete_old_tickets(request: 'OrgRequest') -> None: @OrgApp.cronjob(hour=9, minute=30, timezone='Europe/Zurich') -def send_monthly_mtan_statistics(request: 'OrgRequest') -> None: +def send_monthly_mtan_statistics(request: OrgRequest) -> None: today = to_timezone(utcnow(), 'Europe/Zurich') @@ -684,7 +686,7 @@ def send_monthly_mtan_statistics(request: 'OrgRequest') -> None: @OrgApp.cronjob(hour=4, minute=0, timezone='Europe/Zurich') -def delete_content_marked_deletable(request: 'OrgRequest') -> None: +def delete_content_marked_deletable(request: OrgRequest) -> None: """ Find all models inheriting from DeletableContentExtension, iterate over objects marked as `deletable` and delete them if expired. diff --git a/src/onegov/org/custom.py b/src/onegov/org/custom.py index 3e2d7c6a88..639b7b88f1 100644 --- a/src/onegov/org/custom.py +++ b/src/onegov/org/custom.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.chat import MessageCollection, TextModuleCollection from onegov.core.elements import Link, LinkGroup from onegov.form.collection import FormCollection, SurveyCollection @@ -18,18 +20,18 @@ @OrgApp.template_variables() -def get_template_variables(request: 'OrgRequest') -> dict[str, Any]: +def get_template_variables(request: OrgRequest) -> dict[str, Any]: return { 'global_tools': tuple(get_global_tools(request)) } -def logout_path(request: 'OrgRequest') -> str: +def logout_path(request: OrgRequest) -> str: url = URL(request.link(request.app.org)) return url.path() or '/' -def get_global_tools(request: 'OrgRequest') -> 'Iterator[Link | LinkGroup]': +def get_global_tools(request: OrgRequest) -> Iterator[Link | LinkGroup]: # Authentication / Userprofile if request.is_logged_in: diff --git a/src/onegov/org/directives.py b/src/onegov/org/directives.py index b66c45433f..6f13b32436 100644 --- a/src/onegov/org/directives.py +++ b/src/onegov/org/directives.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from dectate import Action from itertools import count @@ -82,14 +84,14 @@ def __init__(self, tag: str) -> None: def identifier( # type:ignore[override] self, - homepage_widget_registry: dict[str, 'RegisteredHomepageWidget'] + homepage_widget_registry: dict[str, RegisteredHomepageWidget] ) -> str: return self.tag def perform( # type:ignore[override] self, - func: 'Callable[[], HomepageWidget]', - homepage_widget_registry: dict[str, 'RegisteredHomepageWidget'] + func: Callable[[], HomepageWidget], + homepage_widget_registry: dict[str, RegisteredHomepageWidget] ) -> None: widget = cast('RegisteredHomepageWidget', func()) widget.tag = self.tag # keep redundantly for ease of access @@ -117,7 +119,7 @@ def identifier( # type:ignore[override] def perform( # type:ignore[override] self, - cls: 'Callable[..., Any]', + cls: Callable[..., Any], export_registry: dict[str, Any] ) -> None: export_registry[self.id] = cls(**self.kwargs) @@ -137,14 +139,14 @@ def __init__(self) -> None: def identifier( # type:ignore[override] self, - linkgroup_registry: list['LinkGroupFactory'] + linkgroup_registry: list[LinkGroupFactory] ) -> int: return self.name def perform( # type:ignore[override] self, - func: 'LinkGroupFactory', - linkgroup_registry: list['LinkGroupFactory'] + func: LinkGroupFactory, + linkgroup_registry: list[LinkGroupFactory] ) -> None: linkgroup_registry.append(func) @@ -161,14 +163,14 @@ def __init__(self, name: str) -> None: def identifier( # type:ignore[override] self, - directory_search_widget_registry: 'DirectorySearchWidgetRegistry' + directory_search_widget_registry: DirectorySearchWidgetRegistry ) -> str: return self.name def perform( # type:ignore[override] self, - cls: type['DirectorySearchWidget[Any]'], - directory_search_widget_registry: 'DirectorySearchWidgetRegistry' + cls: type[DirectorySearchWidget[Any]], + directory_search_widget_registry: DirectorySearchWidgetRegistry ) -> None: cls = cast('type[RegisteredDirectorySearchWidget[Any]]', cls) @@ -192,14 +194,14 @@ def __init__(self, name: str) -> None: def identifier( # type:ignore[override] self, - event_search_widget_registry: 'EventSearchWidgetRegistry' + event_search_widget_registry: EventSearchWidgetRegistry ) -> str: return self.name def perform( # type:ignore[override] self, - cls: type['EventSearchWidget'], - event_search_widget_registry: 'EventSearchWidgetRegistry' + cls: type[EventSearchWidget], + event_search_widget_registry: EventSearchWidgetRegistry ) -> None: cls = cast('type[RegisteredEventSearchWidget]', cls) @@ -237,14 +239,14 @@ def __init__( def identifier( # type:ignore[override] self, - settings_view_registry: dict[str, 'SettingsDict'] + settings_view_registry: dict[str, SettingsDict] ) -> str: return self.name def perform( # type:ignore[override] self, func: Any, - settings_view_registry: dict[str, 'SettingsDict'] + settings_view_registry: dict[str, SettingsDict] ) -> None: settings_view_registry[self.name] = self.setting @@ -267,14 +269,14 @@ def __init__(self, name: str, order: tuple[int, int]): def identifier( # type:ignore[override] self, - boardlets_registry: dict[str, 'BoardletConfig'] + boardlets_registry: dict[str, BoardletConfig] ) -> str: return self.name def perform( # type:ignore[override] self, - func: type['_Boardlet'], - boardlets_registry: dict[str, 'BoardletConfig'] + func: type[_Boardlet], + boardlets_registry: dict[str, BoardletConfig] ) -> None: boardlets_registry[self.name] = { 'cls': func, diff --git a/src/onegov/org/elements.py b/src/onegov/org/elements.py index 2b91daf07c..23d4ff5d1d 100644 --- a/src/onegov/org/elements.py +++ b/src/onegov/org/elements.py @@ -2,6 +2,8 @@ macros. """ +from __future__ import annotations + from random import choice from lxml.html import builder, tostring @@ -47,7 +49,7 @@ def __init__( self, text: str, url: str, - classes: 'Collection[str] | None' = None, + classes: Collection[str] | None = None, request_method: str = 'GET', attributes: dict[str, Any] | None = None, active: bool = False, @@ -89,8 +91,8 @@ def __eq__(self, other: object) -> bool: def __call__( self, - request: 'ChameleonLayout | CoreRequest', - extra_classes: 'Iterable[str] | None' = None + request: ChameleonLayout | CoreRequest, + extra_classes: Iterable[str] | None = None ) -> Markup: """ Renders the element. """ @@ -169,7 +171,7 @@ def __init__( url: str, title: str | None = None, attrs: dict[str, Any] | None = None, - traits: 'Iterable[Trait] | Trait' = (), + traits: Iterable[Trait] | Trait = (), **props: Any ) -> None: @@ -201,7 +203,7 @@ def __init__( extra_information: str | None = None, redirect_after: str | None = None, request_method: str = 'DELETE', - classes: 'Collection[str]' = ('confirm', 'delete-link'), + classes: Collection[str] = ('confirm', 'delete-link'), target: str | None = None ) -> None: @@ -260,7 +262,7 @@ def __init__( extra_information: str | None = None, redirect_after: str | None = None, request_method: str = 'POST', - classes: 'Collection[str]' = ('confirm', ) + classes: Collection[str] = ('confirm', ) ) -> None: super().__init__( @@ -301,7 +303,7 @@ def __init__( url: str, title: str | None = None, attrs: dict[str, Any] | None = None, - traits: 'Iterable[Trait] | Trait' = (), + traits: Iterable[Trait] | Trait = (), **props: Any ) -> None: diff --git a/src/onegov/org/exports/base.py b/src/onegov/org/exports/base.py index 5c777cac7d..ce25a17982 100644 --- a/src/onegov/org/exports/base.py +++ b/src/onegov/org/exports/base.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.org.models import Export from onegov.town6 import _ @@ -11,7 +13,7 @@ from onegov.ticket import Ticket -def payment_date_paid(payment: 'Payment') -> 'datetime | None': +def payment_date_paid(payment: Payment) -> datetime | None: if not payment.paid: return None if payment.source == 'manual': @@ -27,10 +29,10 @@ class OrgExport(Export): def payment_items_fields( self, - payment: 'Payment', - links: 'Iterable[AnyPayableBase]', + payment: Payment, + links: Iterable[AnyPayableBase], provider_title: str - ) -> 'Iterator[tuple[str, Any]]': + ) -> Iterator[tuple[str, Any]]: yield _('ID Payment Provider'), payment.remote_id yield _('Status'), _(payment.state.capitalize()) @@ -47,8 +49,8 @@ def payment_items_fields( def ticket_item_fields( self, - ticket: 'Ticket | None' - ) -> 'Iterator[tuple[str, Any]]': + ticket: Ticket | None + ) -> Iterator[tuple[str, Any]]: ha = ticket and ticket.handler yield _('Reference Ticket'), ticket and ticket.number diff --git a/src/onegov/org/exports/payments.py b/src/onegov/org/exports/payments.py index f83aefb58c..61f7bdadad 100644 --- a/src/onegov/org/exports/payments.py +++ b/src/onegov/org/exports/payments.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import partial from onegov.core.security import Private @@ -26,8 +28,8 @@ def ticket_by_link( tickets: TicketCollection, - link: 'AnyPayableBase' -) -> 'Ticket | None': + link: AnyPayableBase +) -> Ticket | None: if link.__tablename__ == 'reservations': return tickets.by_handler_id(link.token.hex) # type:ignore @@ -37,8 +39,8 @@ def ticket_by_link( def provider_title( - payment: 'Payment', - providers: dict['UUID', 'PaymentProvider[Any]'] + payment: Payment, + providers: dict[UUID, PaymentProvider[Any]] ) -> str: if not payment.provider_id: @@ -60,10 +62,10 @@ class PaymentsExport(OrgExport): def query( self, - session: 'Session', - start: 'datetime | None', - end: 'datetime | None' - ) -> 'Iterator[tuple[Payment, list[AnyPayableBase], Ticket | None, str]]': + session: Session, + start: datetime | None, + end: datetime | None + ) -> Iterator[tuple[Payment, list[AnyPayableBase], Ticket | None, str]]: tickets = TicketCollection(session) coll = PaymentCollection(session, start=start, end=end) @@ -87,10 +89,10 @@ def query( def rows( self, - session: 'Session', - start: 'datetime | None', - end: 'datetime | None' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + session: Session, + start: datetime | None, + end: datetime | None + ) -> Iterator[Iterator[tuple[str, Any]]]: for item, link, ticket, provider in self.query(session, start, end): yield ( (k, v) for k, v in self.fields(item, link, ticket, provider) @@ -98,20 +100,20 @@ def rows( def fields( self, - item: 'Payment', - links: 'Iterable[AnyPayableBase]', - ticket: 'Ticket | None', + item: Payment, + links: Iterable[AnyPayableBase], + ticket: Ticket | None, provider: str - ) -> 'Iterator[tuple[str, Any]]': + ) -> Iterator[tuple[str, Any]]: yield from self.ticket_item_fields(ticket) yield from self.payment_items_fields(item, links, provider) def run( self, - form: 'Form', - session: 'Session' - ) -> 'Iterator[Iterator[tuple[str, Any]]]': + form: Form, + session: Session + ) -> Iterator[Iterator[tuple[str, Any]]]: timezone = DefaultLayout.timezone start, end = align_range_to_day( diff --git a/src/onegov/org/formats/__init__.py b/src/onegov/org/formats/__init__.py index 86b79b8366..3a2e771fbc 100644 --- a/src/onegov/org/formats/__init__.py +++ b/src/onegov/org/formats/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.org.formats.digirez import DigirezDB __all__ = ['DigirezDB'] diff --git a/src/onegov/org/formats/digirez.py b/src/onegov/org/formats/digirez.py index ff0cb54afa..28fcd41598 100644 --- a/src/onegov/org/formats/digirez.py +++ b/src/onegov/org/formats/digirez.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import csv import os.path import subprocess @@ -59,7 +61,7 @@ def open(self) -> None: stdout=output_file) @property - def records(self) -> 'RecordsAccessor': + def records(self) -> RecordsAccessor: assert self.opened and self.csv_path return RecordsAccessor(self.csv_path) @@ -79,7 +81,7 @@ def get_file(self, name: str) -> IO[bytes]: return self.files[name] - def __getattr__(self, name: str) -> 'Iterator[DefaultRow]': + def __getattr__(self, name: str) -> Iterator[DefaultRow]: csv_file = CSVFile( self.get_file(name), expected_headers=None, diff --git a/src/onegov/org/forms/__init__.py b/src/onegov/org/forms/__init__.py index 745a2119af..bc39017d34 100644 --- a/src/onegov/org/forms/__init__.py +++ b/src/onegov/org/forms/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.org.forms.allocation import AllocationRuleForm from onegov.org.forms.allocation import DaypassAllocationEditForm from onegov.org.forms.allocation import DaypassAllocationForm diff --git a/src/onegov/org/forms/allocation.py b/src/onegov/org/forms/allocation.py index ff2470d9be..0dc2a15c39 100644 --- a/src/onegov/org/forms/allocation.py +++ b/src/onegov/org/forms/allocation.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate from functools import cached_property @@ -30,7 +32,7 @@ class DateContainer(Protocol): def __contains__(self, dt: date | datetime, /) -> bool: ... -def choices_as_integer(choices: 'Iterable[str] | None') -> list[int] | None: +def choices_as_integer(choices: Iterable[str] | None) -> list[int] | None: if choices is None: return None @@ -45,7 +47,7 @@ def generate_dates( end: date | None, start_time: time | None = None, end_time: time | None = None, - weekdays: 'Iterable[int] | None' = None + weekdays: Iterable[int] | None = None ) -> list[tuple[datetime, datetime]]: """ Takes the given dates and generates the date tuples. @@ -195,7 +197,7 @@ def options(self) -> dict[str, Any]: if k not in ('title', 'extend', 'csrf_token') } - def apply(self, resource: 'Resource') -> int: + def apply(self, resource: Resource) -> int: if self.iteration == 0: dates = self.dates else: @@ -250,7 +252,7 @@ class AllocationForm(Form, AllocationFormHelpers): """ if TYPE_CHECKING: - request: 'OrgRequest' + request: OrgRequest start = DateField( label=_('Start'), @@ -325,7 +327,7 @@ def weekdays(self) -> list[int]: return [d[0] for d in WEEKDAYS if d[0] not in exceptions] @cached_property - def exceptions(self) -> 'DateContainer': + def exceptions(self) -> DateContainer: if not hasattr(self, 'request'): return () @@ -338,7 +340,7 @@ def exceptions(self) -> 'DateContainer': return self.request.app.org.holidays @cached_property - def ranged_exceptions(self) -> 'Sequence[tuple[date, date]]': + def ranged_exceptions(self) -> Sequence[tuple[date, date]]: if not hasattr(self, 'request'): return () @@ -361,7 +363,7 @@ def is_excluded(self, dt: datetime) -> bool: return False @property - def dates(self) -> 'SequenceOrScalar[tuple[datetime, datetime]]': + def dates(self) -> SequenceOrScalar[tuple[datetime, datetime]]: """ Passed to :meth:`libres.db.scheduler.Scheduler.allocate`. """ raise NotImplementedError @@ -466,7 +468,7 @@ def quota_limit(self) -> int: return self.daypasses_limit.data # type:ignore[return-value] @property - def dates(self) -> 'Sequence[tuple[datetime, datetime]]': + def dates(self) -> Sequence[tuple[datetime, datetime]]: return self.generate_dates( self.start.data, self.end.data, @@ -500,7 +502,7 @@ def dates(self) -> tuple[datetime, datetime]: def apply_dates(self, start: datetime, end: datetime) -> None: self.date.data = start.date() - def apply_model(self, model: 'Allocation') -> None: + def apply_model(self, model: Allocation) -> None: self.apply_data(model.data) self.date.data = model.display_start().date() self.daypasses.data = model.quota @@ -575,7 +577,7 @@ def partly_available(self) -> bool: return self.is_partly_available.data == 'yes' @property - def dates(self) -> 'Sequence[tuple[datetime, datetime]]': + def dates(self) -> Sequence[tuple[datetime, datetime]]: return self.generate_dates( self.start.data, self.end.data, @@ -622,7 +624,7 @@ def quota_limit(self) -> int: return self.item_limit.data # type:ignore[return-value] @property - def dates(self) -> 'Sequence[tuple[datetime, datetime]]': + def dates(self) -> Sequence[tuple[datetime, datetime]]: return self.generate_dates( self.start.data, self.end.data, @@ -655,7 +657,7 @@ def dates(self) -> tuple[datetime, datetime]: def apply_dates(self, start: datetime, end: datetime) -> None: self.date.data = start.date() - def apply_model(self, model: 'Allocation') -> None: + def apply_model(self, model: Allocation) -> None: self.apply_data(model.data) self.date.data = model.display_start().date() self.items.data = model.quota @@ -748,7 +750,7 @@ def apply_dates(self, start: datetime, end: datetime) -> None: self.start_time.data = start.time() self.end_time.data = end.time() - def apply_model(self, model: 'Allocation') -> None: + def apply_model(self, model: Allocation) -> None: self.apply_data(model.data) self.apply_dates(model.display_start(), model.display_end()) self.as_whole_day.data = model.whole_day and 'yes' or 'no' diff --git a/src/onegov/org/forms/directory.py b/src/onegov/org/forms/directory.py index 981487a4df..bbb166fd39 100644 --- a/src/onegov/org/forms/directory.py +++ b/src/onegov/org/forms/directory.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from wtforms import EmailField @@ -368,7 +370,7 @@ def known_field_ids(self) -> set[str] | None: return None @cached_property - def known_fields(self) -> list['ParsedField'] | None: + def known_fields(self) -> list[ParsedField] | None: try: return list( flatten_fieldsets(parse_formcode(self.structure.data)) @@ -383,7 +385,7 @@ def missing_fields(self) -> dict[str, list[str]] | None: except FormError: return None - def extract_field_ids(self, field: 'Field') -> 'Iterator[str]': + def extract_field_ids(self, field: Field) -> Iterator[str]: if not self.known_field_ids: return @@ -393,27 +395,27 @@ def extract_field_ids(self, field: 'Field') -> 'Iterator[str]': if as_internal_id(line) in self.known_field_ids: yield line - def validate_title_format(self, field: 'Field') -> None: + def validate_title_format(self, field: Field) -> None: if self.missing_fields and 'title' in self.missing_fields: raise ValidationError( _('The following fields are unknown: ${fields}', mapping={ 'fields': ', '.join(self.missing_fields['title']) })) - def validate_lead_format(self, field: 'Field') -> None: + def validate_lead_format(self, field: Field) -> None: if self.missing_fields and 'lead' in self.missing_fields: raise ValidationError( _('The following fields are unknown: ${fields}', mapping={ 'fields': ', '.join(self.missing_fields['lead']) })) - def validate_thumbnail(self, field: 'Field') -> None: + def validate_thumbnail(self, field: Field) -> None: if field.data and '\n' in field.data: raise ValidationError( _('Please select at most one thumbnail field') ) - def validate_numbers(self, field: 'Field') -> None: + def validate_numbers(self, field: Field) -> None: if self.numbering.data == 'custom' and ( '\n' in field.data or field.data == '' ): @@ -461,7 +463,7 @@ def ensure_public_fields_for_submissions(self) -> bool | None: def first_hidden_field( self, configuration: DirectoryConfiguration - ) -> 'ParsedField | None': + ) -> ParsedField | None: """ Returns the first hidden field, or None. """ for field in flatten_fieldsets(parse_formcode(self.structure.data)): @@ -624,7 +626,7 @@ def join(attr: str) -> str | None: self.address_block_title_type.data = 'auto' self.address_block_title.data = '' - def populate_obj(self, obj: 'ExtendedDirectory') -> None: # type:ignore + def populate_obj(self, obj: ExtendedDirectory) -> None: # type:ignore super().populate_obj(obj, exclude={ 'configuration', 'order', @@ -637,7 +639,7 @@ def populate_obj(self, obj: 'ExtendedDirectory') -> None: # type:ignore else: obj.marker_color = self.marker_color - def process_obj(self, obj: 'ExtendedDirectory') -> None: # type:ignore + def process_obj(self, obj: ExtendedDirectory) -> None: # type:ignore self.configuration = obj.configuration if obj.marker_color: @@ -715,19 +717,19 @@ class DirectoryImportForm(Form): ) @staticmethod - def clear_entries(session: 'Session', target: 'ExtendedDirectory') -> None: + def clear_entries(session: Session, target: ExtendedDirectory) -> None: for existing in target.entries: session.delete(existing) target.entries.clear() session.flush() - def run_import(self, target: 'ExtendedDirectory') -> int: + def run_import(self, target: ExtendedDirectory) -> int: session = object_session(target) count = 0 - def count_entry(entry: 'ExtendedDirectoryEntry') -> None: + def count_entry(entry: ExtendedDirectoryEntry) -> None: nonlocal count count += 1 diff --git a/src/onegov/org/forms/event.py b/src/onegov/org/forms/event.py index 5a7826b260..e5ff7487f0 100644 --- a/src/onegov/org/forms/event.py +++ b/src/onegov/org/forms/event.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import json import transaction @@ -365,7 +367,7 @@ def ensure_valid_rrule(self) -> bool | None: return None - def populate_obj(self, model: 'Event') -> None: # type:ignore[override] + def populate_obj(self, model: Event) -> None: # type:ignore[override] """ Stores the form values on the model. """ super().populate_obj(model, exclude={ @@ -428,7 +430,7 @@ def populate_obj(self, model: 'Event') -> None: # type:ignore[override] for occ in model.occurrences: occ.filter_keywords = filter_keywords - def process_obj(self, model: 'Event') -> None: # type:ignore[override] + def process_obj(self, model: Event) -> None: # type:ignore[override] """ Stores the page values on the form. """ super().process_obj(model) @@ -488,7 +490,7 @@ def json_to_dates(self, text: str | None = None) -> list[date]: for value in json.loads(text).get('values', []) ] - def dates_to_json(self, dates: 'Sequence[date] | None' = None) -> str: + def dates_to_json(self, dates: Sequence[date] | None = None) -> str: dates = dates or [] return json.dumps({ @@ -576,7 +578,7 @@ def run_export(self) -> list[dict[str, str]]: occurrences = OccurrenceCollection(self.request.session) headers = self.headers - def get(occurrence: 'Occurrence', attribute: str) -> str: + def get(occurrence: Occurrence, attribute: str) -> str: if attribute in ('start', 'end'): attribute = f'localized_{attribute}' result = ( @@ -639,7 +641,7 @@ def run_import(self) -> tuple[int, list[str]]: for key, value in headers.items() } - def get(line: 'DefaultRow', column: str, attribute: str) -> Any: + def get(line: DefaultRow, column: str, attribute: str) -> Any: result = getattr(line, column) if attribute in ('start', 'end'): result = parse(result, dayfirst=True) diff --git a/src/onegov/org/forms/extensions.py b/src/onegov/org/forms/extensions.py index bc05f7d330..c00d9dc8fc 100644 --- a/src/onegov/org/forms/extensions.py +++ b/src/onegov/org/forms/extensions.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from sedate import utcnow, to_timezone @@ -142,7 +144,7 @@ def target(self) -> ExtendedDirectoryEntry | None: .first() ) - def is_different(self, field: 'Field') -> bool: + def is_different(self, field: Field) -> bool: # if the target has been removed, stop if not self.target: return True @@ -178,9 +180,9 @@ def is_different(self, field: 'Field') -> bool: def render_original( self, - field: 'Field', + field: Field, from_model: bool = False - ) -> 'Markup': + ) -> Markup: prev = field.data @@ -198,7 +200,7 @@ def render_original( finally: field.data = prev - def render_display(self, field: 'Field') -> 'Markup | None': + def render_display(self, field: Field) -> Markup | None: if self.is_different(field): proposed = super().render_display(field) diff --git a/src/onegov/org/forms/external_link.py b/src/onegov/org/forms/external_link.py index 64adf9baa7..ac9c12766c 100644 --- a/src/onegov/org/forms/external_link.py +++ b/src/onegov/org/forms/external_link.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.org import _ from onegov.org.models.external_link import ExternalLinkCollection diff --git a/src/onegov/org/forms/fields.py b/src/onegov/org/forms/fields.py index 20d3e09eef..6f5c95576b 100644 --- a/src/onegov/org/forms/fields.py +++ b/src/onegov/org/forms/fields.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.file import File, FileCollection from onegov.core.utils import binary_to_dictionary, dictionary_to_binary from onegov.form.fields import HtmlField as HtmlFieldBase @@ -23,7 +25,7 @@ class HtmlField(HtmlFieldBase): """ - def pre_validate(self, form: 'Form') -> None: # type:ignore[override] + def pre_validate(self, form: Form) -> None: # type:ignore[override] super().pre_validate(form) self.data = remove_empty_paragraphs( annotate_html( @@ -179,7 +181,7 @@ def __init__( _choices = file_choices_from_collection(self.collection) self.choices = _choices - def process_formdata(self, valuelist: list['RawFormValue']) -> None: + def process_formdata(self, valuelist: list[RawFormValue]) -> None: if not valuelist: self.data = {} @@ -297,7 +299,7 @@ def __init__( _choices=self.choices, ) - def process_formdata(self, valuelist: list['RawFormValue']) -> None: + def process_formdata(self, valuelist: list[RawFormValue]) -> None: if not valuelist: return diff --git a/src/onegov/org/forms/form_definition.py b/src/onegov/org/forms/form_definition.py index fd3b08783d..25e4bfe0f6 100644 --- a/src/onegov/org/forms/form_definition.py +++ b/src/onegov/org/forms/form_definition.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import normalize_for_url from onegov.form import Form, merge_forms, FormDefinitionCollection from onegov.form.validators import ValidFormDefinition, ValidSurveyDefinition diff --git a/src/onegov/org/forms/form_export.py b/src/onegov/org/forms/form_export.py index aa94a8938a..a9d6a39627 100644 --- a/src/onegov/org/forms/form_export.py +++ b/src/onegov/org/forms/form_export.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import merge_forms from onegov.form.fields import MultiCheckboxField from onegov.org import _ diff --git a/src/onegov/org/forms/form_registration.py b/src/onegov/org/forms/form_registration.py index a3a8926044..124f845bd2 100644 --- a/src/onegov/org/forms/form_registration.py +++ b/src/onegov/org/forms/form_registration.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.form import Form, FormDefinition from onegov.form.fields import MultiCheckboxField @@ -48,7 +50,7 @@ def ensure_receivers(self) -> bool | None: return None @property - def receivers(self) -> dict[str, 'FormSubmission']: + def receivers(self) -> dict[str, FormSubmission]: registration_state = self.registration_state.data assert registration_state is not None return { @@ -110,7 +112,7 @@ class FormRegistrationWindowForm(Form): def process_obj( self, - obj: 'FormRegistrationWindow' # type:ignore[override] + obj: FormRegistrationWindow # type:ignore[override] ) -> None: super().process_obj(obj) @@ -121,7 +123,7 @@ def process_obj( def populate_obj( # type:ignore[override] self, - obj: 'FormRegistrationWindow', # type:ignore[override] + obj: FormRegistrationWindow, # type:ignore[override] *args: Any, **kwargs: Any, ) -> None: diff --git a/src/onegov/org/forms/generic.py b/src/onegov/org/forms/generic.py index 37379e5511..9fe80a536c 100644 --- a/src/onegov/org/forms/generic.py +++ b/src/onegov/org/forms/generic.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from dicttoxml import dicttoxml # type:ignore[import-untyped] from morepath.request import Response from onegov.core.csv import convert_list_of_dicts_to_csv @@ -72,7 +74,7 @@ def format(self) -> str: def as_export_response( self, - results: 'Sequence[dict[str, Any]]', + results: Sequence[dict[str, Any]], title: str = 'export', **kwargs: Any ) -> Response: @@ -171,7 +173,7 @@ class ChangeAdjacencyListUrlForm(Form): default=True ) - def get_model(self) -> 'AdjacencyList': + def get_model(self) -> AdjacencyList: return self.model def validate_name(self, field: StringField) -> None: diff --git a/src/onegov/org/forms/imageset.py b/src/onegov/org/forms/imageset.py index 3edb063f7f..2a2cf35dd4 100644 --- a/src/onegov/org/forms/imageset.py +++ b/src/onegov/org/forms/imageset.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.org import _ from wtforms.fields import BooleanField @@ -25,3 +27,22 @@ class ImageSetForm(Form): show_images_on_homepage = BooleanField( label=_('Show images on homepage')) + + order = RadioField( + label=_('Order'), + fieldset=_('Order'), + choices=[ + ('by-name', _('By filename')), + ('by-caption', _('By caption')), + ('by-last-change', _('By last change')) + ], + default='by-last-change') + + order_direction = RadioField( + label=_('Direction'), + fieldset=_('Order'), + choices=[ + ('asc', _('Ascending')), + ('desc', _('Descending')) + ], + default='desc') diff --git a/src/onegov/org/forms/mtan.py b/src/onegov/org/forms/mtan.py index 6b39c43d0f..c7b8f35c3c 100644 --- a/src/onegov/org/forms/mtan.py +++ b/src/onegov/org/forms/mtan.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form.fields import HoneyPotField from onegov.user.forms import MTANForm from onegov.user.forms import RequestMTANForm diff --git a/src/onegov/org/forms/newsletter.py b/src/onegov/org/forms/newsletter.py index 8a6ce7a2f7..deb556b3c8 100644 --- a/src/onegov/org/forms/newsletter.py +++ b/src/onegov/org/forms/newsletter.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import timedelta import transaction from wtforms.validators import DataRequired @@ -52,26 +54,26 @@ class NewsletterForm(Form): # FIXME: Why are we passing the request in? It should alread be stored on # the form itself. - def update_model(self, model: 'Newsletter', request: 'OrgRequest') -> None: + def update_model(self, model: Newsletter, request: OrgRequest) -> None: assert self.title.data is not None model.title = self.title.data model.lead = self.lead.data model.html = self.get_html(request) - def apply_model(self, model: 'Newsletter') -> None: + def apply_model(self, model: Newsletter) -> None: self.title.data = model.title self.lead.data = model.lead # FIXME: same here - def get_html(self, request: 'OrgRequest') -> str: + def get_html(self, request: OrgRequest) -> str: return '' @classmethod def with_news( cls, - request: 'OrgRequest', - news: 'Iterable[News]' - ) -> type['Self']: + request: OrgRequest, + news: Iterable[News] + ) -> type[Self]: # FIXME: using a layout just for format_date seems bad, we should # probably extract these functions into util modules @@ -113,8 +115,8 @@ class NewsletterWithNewsForm(cls): # type:ignore def update_model( self, - model: 'Newsletter', - request: 'OrgRequest' # FIXME: same here + model: Newsletter, + request: OrgRequest # FIXME: same here ) -> None: super().update_model(model, request) @@ -122,7 +124,7 @@ def update_model( model.content['show_news_as_tiles'] = ( self.show_news_as_tiles.data) - def apply_model(self, model: 'Newsletter') -> None: + def apply_model(self, model: Newsletter) -> None: super().apply_model(model) self.news.data = model.content.get('news') self.show_news_as_tiles.data = model.content.get( @@ -133,9 +135,9 @@ def apply_model(self, model: 'Newsletter') -> None: @classmethod def with_occurrences( cls, - request: 'OrgRequest', - occurrences: 'Iterable[Occurrence]' - ) -> type['Self']: + request: OrgRequest, + occurrences: Iterable[Occurrence] + ) -> type[Self]: # FIXME: another use of layout for format_date layout = Layout(None, request) @@ -169,14 +171,14 @@ class NewsletterWithOccurrencesForm(cls): # type:ignore def update_model( self, - model: 'Newsletter', - request: 'OrgRequest' # FIXME: same here + model: Newsletter, + request: OrgRequest # FIXME: same here ) -> None: super().update_model(model, request) model.content['occurrences'] = self.occurrences.data - def apply_model(self, model: 'Newsletter') -> None: + def apply_model(self, model: Newsletter) -> None: super().apply_model(model) self.occurrences.data = model.content.get('occurrences') @@ -185,9 +187,9 @@ def apply_model(self, model: 'Newsletter') -> None: @classmethod def with_publications( cls, - request: 'OrgRequest', - publications: 'Iterable[File]' - ) -> type['Self']: + request: OrgRequest, + publications: Iterable[File] + ) -> type[Self]: # FIXME: another use of layout for format_date layout = Layout(None, request) @@ -221,14 +223,14 @@ class NewsletterWithPublicationsForm(cls): # type:ignore def update_model( self, - model: 'Newsletter', - request: 'OrgRequest' # FIXME: same here + model: Newsletter, + request: OrgRequest # FIXME: same here ) -> None: super().update_model(model, request) model.content['publications'] = self.publications.data - def apply_model(self, model: 'Newsletter') -> None: + def apply_model(self, model: Newsletter) -> None: super().apply_model(model) self.publications.data = model.content.get('publications') @@ -410,7 +412,7 @@ def run_import(self) -> tuple[int, list[str]]: for key, value in headers.items() } - def get(line: 'DefaultRow', column: str) -> Any: + def get(line: DefaultRow, column: str) -> Any: return getattr(line, column) count = 0 diff --git a/src/onegov/org/forms/page.py b/src/onegov/org/forms/page.py index 6d914c052d..62d6b9a1e5 100644 --- a/src/onegov/org/forms/page.py +++ b/src/onegov/org/forms/page.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.form.fields import ChosenSelectField from onegov.org import _ @@ -129,7 +131,7 @@ def validate_url(self, field: URLField) -> None: class PageUrlForm(ChangeAdjacencyListUrlForm): - def get_model(self) -> 'Page': + def get_model(self) -> Page: return self.model.page @@ -156,9 +158,9 @@ def on_request(self) -> None: def iterate_page_tree( self, - pages: 'Iterable[Page]', + pages: Iterable[Page], indent: str = '', - ) -> 'Iterator[tuple[int, str]]': + ) -> Iterator[tuple[int, str]]: """ Iterates over the page tree and lists the elements with ident to show the page hierarchy in the choices list @@ -195,7 +197,7 @@ def validate_parent_id(self, field: ChosenSelectField) -> None: ): raise ValidationError(_('Invalid destination selected')) - def update_model(self, model: 'Page') -> None: + def update_model(self, model: Page) -> None: session = self.request.session pages = PageCollection(session) diff --git a/src/onegov/org/forms/person.py b/src/onegov/org/forms/person.py index c3839fe218..4120d0cb9f 100644 --- a/src/onegov/org/forms/person.py +++ b/src/onegov/org/forms/person.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.utils import ensure_scheme from onegov.form import Form from onegov.org import _ diff --git a/src/onegov/org/forms/reservation.py b/src/onegov/org/forms/reservation.py index 8b98510b55..1a91600621 100644 --- a/src/onegov/org/forms/reservation.py +++ b/src/onegov/org/forms/reservation.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import date, time, timedelta from functools import cached_property from uuid import UUID @@ -110,7 +112,7 @@ def on_request(self) -> None: self.start.data = date.today() self.end.data = self.start.data + timedelta(days=7) - def apply_rooms(self, rooms: 'Sequence[Resource]') -> None: + def apply_rooms(self, rooms: Sequence[Resource]) -> None: if len(rooms) < 2: # no need to filter self.delete_field('rooms') @@ -154,7 +156,7 @@ def ensure_start_time_before_end_time(self) -> bool | None: return None @cached_property - def exceptions(self) -> 'DateContainer': + def exceptions(self) -> DateContainer: if not hasattr(self, 'request'): return () @@ -167,7 +169,7 @@ def exceptions(self) -> 'DateContainer': return self.request.app.org.holidays @cached_property - def ranged_exceptions(self) -> 'Sequence[tuple[date, date]]': + def ranged_exceptions(self) -> Sequence[tuple[date, date]]: if not hasattr(self, 'request'): return () @@ -202,9 +204,9 @@ def format(self) -> str: def as_multiple_export_response( self, - keys: 'Sequence[StrKeyFunc | None] | None', - results: 'Sequence[Iterable[dict[str, Any]]]', - titles: 'Sequence[str]' + keys: Sequence[StrKeyFunc | None] | None, + results: Sequence[Iterable[dict[str, Any]]], + titles: Sequence[str] ) -> bytes: return convert_list_of_list_of_dicts_to_xlsx( diff --git a/src/onegov/org/forms/resource.py b/src/onegov/org/forms/resource.py index 3410f68298..4e6d295fac 100644 --- a/src/onegov/org/forms/resource.py +++ b/src/onegov/org/forms/resource.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from wtforms.fields import BooleanField from wtforms.fields import DecimalField from wtforms.fields import IntegerField @@ -305,12 +307,12 @@ def zipcode_block(self, value: dict[str, Any] | None) -> None: self.zipcode_list.data = '\n'.join( str(i) for i in sorted(value['zipcode_list'])) - def populate_obj(self, obj: 'Resource') -> None: # type:ignore + def populate_obj(self, obj: Resource) -> None: # type:ignore super().populate_obj(obj, exclude=('deadline', 'zipcode_block')) obj.deadline = self.deadline obj.zipcode_block = self.zipcode_block - def process_obj(self, obj: 'Resource') -> None: # type:ignore + def process_obj(self, obj: Resource) -> None: # type:ignore super().process_obj(obj) self.deadline = obj.deadline self.zipcode_block = obj.zipcode_block diff --git a/src/onegov/org/forms/resource_recipient.py b/src/onegov/org/forms/resource_recipient.py index 8e5f6538e6..6cef1b62af 100644 --- a/src/onegov/org/forms/resource_recipient.py +++ b/src/onegov/org/forms/resource_recipient.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.form.fields import MultiCheckboxField from onegov.org import _ diff --git a/src/onegov/org/forms/settings.py b/src/onegov/org/forms/settings.py index bf304996d1..bb22439c07 100644 --- a/src/onegov/org/forms/settings.py +++ b/src/onegov/org/forms/settings.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import datetime import json import re @@ -142,19 +144,19 @@ def theme_options(self, options: dict[str, Any]) -> None: 'font-family-sans-serif') or self.default_font_family @cached_property - def theme(self) -> 'OrgTheme': + def theme(self) -> OrgTheme: return self.request.app.settings.core.theme @property def default_font_family(self) -> str | None: return self.theme.default_options.get('font-family-sans-serif') - def populate_obj(self, model: 'Organisation') -> None: # type:ignore + def populate_obj(self, model: Organisation) -> None: # type:ignore super().populate_obj(model) model.theme_options = self.theme_options model.custom_css = self.custom_css.data or '' - def process_obj(self, model: 'Organisation') -> None: # type:ignore + def process_obj(self, model: Organisation) -> None: # type:ignore super().process_obj(model) self.theme_options = model.theme_options or {} self.custom_css.data = model.custom_css or '' @@ -168,7 +170,7 @@ def on_request(self) -> None: self.populate_font_families() @self.request.after - def clear_locale(response: 'Response') -> None: + def clear_locale(response: Response) -> None: response.delete_cookie('locale') @@ -581,11 +583,11 @@ def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.link_errors = {} - def populate_obj(self, model: 'Organisation') -> None: # type:ignore + def populate_obj(self, model: Organisation) -> None: # type:ignore super().populate_obj(model) model.header_options = self.header_options - def process_obj(self, model: 'Organisation') -> None: # type:ignore + def process_obj(self, model: Organisation) -> None: # type:ignore super().process_obj(model) self.header_options = model.header_options or {} @@ -615,7 +617,7 @@ def json_to_links( def links_to_json( self, - header_links: 'Sequence[tuple[str | None, str | None]] | None' = None + header_links: Sequence[tuple[str | None, str | None]] | None = None ) -> str: header_links = header_links or [] @@ -800,10 +802,10 @@ def derive_analytics_url(self) -> str: else: return '' - def populate_obj(self, model: 'Organisation') -> None: # type:ignore + def populate_obj(self, model: Organisation) -> None: # type:ignore super().populate_obj(model) - def process_obj(self, model: 'Organisation') -> None: # type:ignore + def process_obj(self, model: Organisation) -> None: # type:ignore super().process_obj(model) self.analytics_url.text = self.derive_analytics_url() @@ -983,10 +985,10 @@ def format_school(d: tuple[int, int, int, int, int, int]) -> str: self.school_holidays.data = '\n'.join( format_school(d) for d in data.get('school', ())) - def populate_obj(self, model: 'Organisation') -> None: # type:ignore + def populate_obj(self, model: Organisation) -> None: # type:ignore model.holiday_settings = self.holiday_settings - def process_obj(self, model: 'Organisation') -> None: # type:ignore + def process_obj(self, model: Organisation) -> None: # type:ignore self.holiday_settings = model.holiday_settings @@ -1213,14 +1215,14 @@ def ensure_categories(self) -> bool | None: return None - def populate_obj(self, model: 'Organisation') -> None: # type:ignore + def populate_obj(self, model: Organisation) -> None: # type:ignore super().populate_obj(model) yaml_data = self.newsletter_categories.data data = yaml.safe_load(yaml_data) if yaml_data else {} model.newsletter_categories = data - def process_obj(self, model: 'Organisation') -> None: # type:ignore + def process_obj(self, model: Organisation) -> None: # type:ignore super().process_obj(model) categories = model.newsletter_categories or {} @@ -1274,7 +1276,7 @@ class LinkHealthCheckForm(Form): ) -def validate_https(form: Form, field: 'Field') -> None: +def validate_https(form: Form, field: Field) -> None: if not field.data.startswith('https'): raise ValidationError(_("Link must start with 'https'")) @@ -1302,7 +1304,7 @@ class GeverSettingsForm(Form): description=_('Website address including https://'), ) - def populate_obj(self, model: 'Organisation') -> None: # type:ignore + def populate_obj(self, model: Organisation) -> None: # type:ignore super().populate_obj(model) key_base64 = self.request.app.hashed_identity_key try: @@ -1315,7 +1317,7 @@ def populate_obj(self, model: 'Organisation') -> None: # type:ignore model.gever_username = '' model.gever_password = '' # nosec: B105 - def process_obj(self, model: 'Organisation') -> None: # type:ignore + def process_obj(self, model: Organisation) -> None: # type:ignore super().process_obj(model) self.gever_username.data = model.gever_username or '' diff --git a/src/onegov/org/forms/signup.py b/src/onegov/org/forms/signup.py index 1e6b401176..8e4aa05c99 100644 --- a/src/onegov/org/forms/signup.py +++ b/src/onegov/org/forms/signup.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.form.fields import HoneyPotField, MultiCheckboxField from onegov.org import _ @@ -15,7 +17,7 @@ class SignupForm(Form): - request: 'OrgRequest' + request: OrgRequest address = StringField( label=_('E-Mail Address'), diff --git a/src/onegov/org/forms/survey_export.py b/src/onegov/org/forms/survey_export.py index dc1482ff2a..0fdd3e5433 100644 --- a/src/onegov/org/forms/survey_export.py +++ b/src/onegov/org/forms/survey_export.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import merge_forms from onegov.form.fields import MultiCheckboxField from onegov.org import _ diff --git a/src/onegov/org/forms/survey_submission.py b/src/onegov/org/forms/survey_submission.py index 4d0fd1344b..22679c9ca0 100644 --- a/src/onegov/org/forms/survey_submission.py +++ b/src/onegov/org/forms/survey_submission.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from wtforms import StringField from onegov.form import Form from onegov.org import _ @@ -35,14 +37,14 @@ class SurveySubmissionWindowForm(Form): def process_obj( self, - obj: 'SurveySubmissionWindow' # type:ignore[override] + obj: SurveySubmissionWindow # type:ignore[override] ) -> None: super().process_obj(obj) def populate_obj( # type:ignore[override] self, - obj: 'SurveySubmissionWindow', # type:ignore[override] + obj: SurveySubmissionWindow, # type:ignore[override] *args: Any, **kwargs: Any, ) -> None: diff --git a/src/onegov/org/forms/text_module.py b/src/onegov/org/forms/text_module.py index ece9a2781f..0ef052975b 100644 --- a/src/onegov/org/forms/text_module.py +++ b/src/onegov/org/forms/text_module.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.form.filters import strip_whitespace from onegov.org import _ diff --git a/src/onegov/org/forms/ticket.py b/src/onegov/org/forms/ticket.py index e907b92385..87013e33e3 100644 --- a/src/onegov/org/forms/ticket.py +++ b/src/onegov/org/forms/ticket.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.chat import MessageFile from onegov.core.security import Private from onegov.form import Form diff --git a/src/onegov/org/forms/user.py b/src/onegov/org/forms/user.py index dfcd817cad..0849ab3e51 100644 --- a/src/onegov/org/forms/user.py +++ b/src/onegov/org/forms/user.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.utils import is_valid_yubikey_format from onegov.directory.models.directory import Directory @@ -233,7 +235,7 @@ def on_request(self) -> None: ) self.ticket_permissions.choices = sorted(ticket_choices) - def update_model(self, model: 'UserGroup') -> None: + def update_model(self, model: UserGroup) -> None: session = self.request.session # Logout the new and old users @@ -276,7 +278,7 @@ def update_model(self, model: 'UserGroup') -> None: model.meta = {} model.meta['directories'] = self.directories.data - def apply_model(self, model: 'UserGroup') -> None: + def apply_model(self, model: UserGroup) -> None: self.name.data = model.name self.users.data = [str(u.id) for u in model.users] # FIXME: backref across module boundaries diff --git a/src/onegov/org/forms/userprofile.py b/src/onegov/org/forms/userprofile.py index b49493683f..9ec7327580 100644 --- a/src/onegov/org/forms/userprofile.py +++ b/src/onegov/org/forms/userprofile.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form import Form from onegov.org import _ from wtforms.fields import RadioField @@ -46,7 +48,7 @@ def on_request(self) -> None: if not self.enable_ticket_statistics: self.delete_field('ticket_statistics') - def populate_obj(self, obj: 'User') -> None: # type:ignore + def populate_obj(self, obj: User) -> None: # type:ignore super().populate_obj(obj, exclude={ 'ticket_statistics', }) @@ -55,7 +57,7 @@ def populate_obj(self, obj: 'User') -> None: # type:ignore obj.data = obj.data or {} obj.data['ticket_statistics'] = self.ticket_statistics.data - def process_obj(self, obj: 'User') -> None: # type:ignore + def process_obj(self, obj: User) -> None: # type:ignore super().process_obj(obj) if self.enable_ticket_statistics: diff --git a/src/onegov/org/forms/util.py b/src/onegov/org/forms/util.py index a2d76d912a..2461e33665 100644 --- a/src/onegov/org/forms/util.py +++ b/src/onegov/org/forms/util.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from dateutil.rrule import MO, TU, WE, TH, FR, SA, SU from onegov.org import _ diff --git a/src/onegov/org/forms/widgets.py b/src/onegov/org/forms/widgets.py index e9cb454783..9245d0cbf4 100644 --- a/src/onegov/org/forms/widgets.py +++ b/src/onegov/org/forms/widgets.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from markupsafe import Markup from onegov.form.widgets import UploadWidget, UploadMultipleWidget from onegov.org import _ @@ -26,7 +28,7 @@ class UploadOrLinkExistingFileWidget(UploadWidget): def template_data( self, - field: 'UploadOrSelectExistingFileField', # type:ignore[override] + field: UploadOrSelectExistingFileField, # type:ignore[override] force_simple: bool, resend_upload: bool, wrapper_css_class: str, @@ -129,7 +131,7 @@ class UploadOrSelectExistingFileWidget(UploadOrLinkExistingFileWidget): def template_data( self, - field: 'UploadOrSelectExistingFileField', # type:ignore[override] + field: UploadOrSelectExistingFileField, # type:ignore[override] force_simple: bool, resend_upload: bool, wrapper_css_class: str, @@ -172,7 +174,7 @@ class UploadOrSelectExistingMultipleFilesWidget(UploadMultipleWidget): def render_input( self, - field: 'UploadOrSelectExistingMultipleFilesField', # type:ignore + field: UploadOrSelectExistingMultipleFilesField, # type:ignore **kwargs: Any ) -> Markup: diff --git a/src/onegov/org/homepage_widgets.py b/src/onegov/org/homepage_widgets.py index 6c07f27a4c..ab32759d5b 100644 --- a/src/onegov/org/homepage_widgets.py +++ b/src/onegov/org/homepage_widgets.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.directory import DirectoryCollection from onegov.event import OccurrenceCollection from onegov.org import _, OrgApp @@ -134,7 +136,7 @@ class DirectoriesWidget: """ - def get_variables(self, layout: 'DefaultLayout') -> 'RenderData': + def get_variables(self, layout: DefaultLayout) -> RenderData: directories: DirectoryCollection[ExtendedDirectory] directories = DirectoryCollection( layout.app.session(), type='extended') @@ -178,7 +180,7 @@ class NewsWidget: """ - def get_variables(self, layout: 'DefaultLayout') -> 'RenderData': + def get_variables(self, layout: DefaultLayout) -> RenderData: root_pages = layout.root_pages if not root_pages: @@ -214,7 +216,7 @@ def get_variables(self, layout: 'DefaultLayout') -> 'RenderData': ) # limits the news, but doesn't count sticky news towards that limit - def limited(news: 'Iterable[News]', limit: int) -> 'Iterator[News]': + def limited(news: Iterable[News], limit: int) -> Iterator[News]: count = 0 for item in news: @@ -251,7 +253,7 @@ class EventsWidget: """ - def get_variables(self, layout: 'DefaultLayout') -> 'RenderData': + def get_variables(self, layout: DefaultLayout) -> RenderData: occurrences = OccurrenceCollection(layout.app.session()).query() occurrences = occurrences.limit(layout.org.event_limit_homepage) @@ -299,15 +301,15 @@ class TilesWidget: """ - def get_variables(self, layout: 'DefaultLayout') -> 'RenderData': + def get_variables(self, layout: DefaultLayout) -> RenderData: return {'tiles': tuple(self.get_tiles(layout))} class Tile(NamedTuple): page: Link - links: 'Sequence[Link]' + links: Sequence[Link] number: int - def get_tiles(self, layout: 'DefaultLayout') -> 'Iterator[Tile]': + def get_tiles(self, layout: DefaultLayout) -> Iterator[Tile]: request = layout.request homepage_pages = request.homepage_pages @@ -361,8 +363,8 @@ class SliderWidget: def get_images_from_sets( self, - layout: 'DefaultLayout' - ) -> 'Iterator[RenderData]': + layout: DefaultLayout + ) -> Iterator[RenderData]: session = layout.app.session() @@ -393,7 +395,7 @@ def get_images_from_sets( 'src': layout.request.link(image) } - def get_variables(self, layout: 'DefaultLayout') -> 'RenderData': + def get_variables(self, layout: DefaultLayout) -> RenderData: # if we don't have an album used for images, we use the images # shown on the homepage anyway to avoid having to show nothing images = tuple(self.get_images_from_sets(layout)) diff --git a/src/onegov/org/i18n.py b/src/onegov/org/i18n.py index 2f5b95095c..a5e7a3bc82 100644 --- a/src/onegov/org/i18n.py +++ b/src/onegov/org/i18n.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.i18n.translation_string import TranslationStringFactory _ = TranslationStringFactory('onegov.org') diff --git a/src/onegov/org/initial_content.py b/src/onegov/org/initial_content.py index 0089a0d76b..fe080226e1 100644 --- a/src/onegov/org/initial_content.py +++ b/src/onegov/org/initial_content.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import codecs import os import yaml @@ -32,7 +34,7 @@ def load_content(path: str) -> dict[str, Any]: return yaml.safe_load(f) -def absolute_path(path: str, base: 'StrPath') -> str: +def absolute_path(path: str, base: StrPath) -> str: if path.startswith('/'): return path if path.startswith('~'): @@ -42,7 +44,7 @@ def absolute_path(path: str, base: 'StrPath') -> str: def create_new_organisation( - app: 'OrgApp', + app: OrgApp, name: str, create_files: bool = True, path: str | None = None, @@ -67,7 +69,7 @@ def create_new_organisation( translator = app.translations.get(locale) assert translator is not None - def translate(text: 'TranslationString') -> str: + def translate(text: TranslationString) -> str: return text.interpolate(translator.gettext(text)) add_pages(session, path) @@ -81,7 +83,7 @@ def translate(text: 'TranslationString') -> str: return org -def add_pages(session: 'Session', path: str) -> None: +def add_pages(session: Session, path: str) -> None: pages = PageCollection(session) for ix, page in enumerate(load_content(path).get('pages', ())): @@ -102,8 +104,8 @@ def add_pages(session: 'Session', path: str) -> None: def add_builtin_forms( - session: 'Session', - definitions: 'Iterable[tuple[str, str, str]] | None' = None, + session: Session, + definitions: Iterable[tuple[str, str, str]] | None = None, locale: str = 'de_CH' ) -> None: @@ -125,9 +127,9 @@ def add_builtin_forms( def builtin_form_definitions( - path: 'StrPath | None' = None, + path: StrPath | None = None, locale: str = 'de_CH' -) -> 'Iterator[tuple[str, str, str]]': +) -> Iterator[tuple[str, str, str]]: """ Yields the name, title and the form definition of all form definitions in the given or the default path. @@ -160,8 +162,8 @@ def load_definition(path: str) -> tuple[str, str]: def add_resources( - libres_context: 'LibresContext', - translate: 'Callable[[TranslationString], str]' + libres_context: LibresContext, + translate: Callable[[TranslationString], str] ) -> None: resource = ResourceCollection(libres_context) @@ -180,7 +182,7 @@ def add_resources( def add_filesets( - session: 'Session', + session: Session, organisation_name: str, path: str ) -> None: @@ -214,9 +216,9 @@ def add_filesets( def add_events( - session: 'Session', + session: Session, name: str, - translate: 'Callable[[TranslationString], str]', + translate: Callable[[TranslationString], str], create_files: bool ) -> None: diff --git a/src/onegov/org/layout.py b/src/onegov/org/layout.py index 1afb71eed1..0d2604d2db 100644 --- a/src/onegov/org/layout.py +++ b/src/onegov/org/layout.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import babel.dates import re @@ -80,12 +82,15 @@ from onegov.ticket import Ticket from onegov.user import User, UserGroup from sedate.types import TzInfoOrName - from typing import TypeVar + from typing import TypeAlias, TypeVar from webob import Response from wtforms import Field _T = TypeVar('_T') + AnyFormDefinitionOrCollection: TypeAlias = ( + FormDefinition | FormCollection | SurveyCollection | SurveyDefinition) + capitalised_name = re.compile(r'[A-Z]{1}[a-z]+') @@ -110,8 +115,8 @@ def view_example(self, request): """ - app: 'OrgApp' - request: 'OrgRequest' + app: OrgApp + request: OrgRequest date_long_without_year_format = 'E d. MMMM' datetime_long_without_year_format = 'E d. MMMM HH:mm' @@ -120,7 +125,7 @@ def view_example(self, request): event_short_format = 'EE d. MMMM YYYY' isodate_format = 'y-M-d' - def has_model_permission(self, permission: type['Intent'] | None) -> bool: + def has_model_permission(self, permission: type[Intent] | None) -> bool: return self.request.has_permission(self.model, permission) @property @@ -135,7 +140,7 @@ def name(self) -> str: ) @property - def org(self) -> 'Organisation': + def org(self) -> Organisation: """ An alias for self.request.app.org. """ return self.request.app.org @@ -169,7 +174,7 @@ def default_map_view(self) -> dict[str, Any]: } @cached_property - def svg(self) -> 'PageTemplateFile': + def svg(self) -> PageTemplateFile: return self.template_loader['svg.pt'] @cached_property @@ -211,7 +216,7 @@ def page_id(self) -> str: return 'page-' + (page_id or 'root') @cached_property - def body_classes(self) -> 'Iterator[str]': + def body_classes(self) -> Iterator[str]: """ Yields a list of body classes used on the body. """ if self.request.is_logged_in: @@ -223,7 +228,7 @@ def body_classes(self) -> 'Iterator[str]': yield self.name @cached_property - def top_navigation(self) -> 'Sequence[Link] | None': + def top_navigation(self) -> Sequence[Link] | None: """ Returns a list of :class:`onegov.org.elements.Link` objects. Those links are used for the top navigation. @@ -233,7 +238,7 @@ def top_navigation(self) -> 'Sequence[Link] | None': return None @cached_property - def breadcrumbs(self) -> 'Sequence[Link] | None': + def breadcrumbs(self) -> Sequence[Link] | None: """ Returns a list of :class:`onegov.org.elements.Link` objects. Those links are used for the breadcrumbs. @@ -243,12 +248,12 @@ def breadcrumbs(self) -> 'Sequence[Link] | None': return None @cached_property - def sidebar_links(self) -> 'Sequence[Link | LinkGroup] | None': + def sidebar_links(self) -> Sequence[Link | LinkGroup] | None: """ A list of links shown in the sidebar, used for navigation. """ return None @cached_property - def editbar_links(self) -> 'Sequence[BaseLink | LinkGroup] | None': + def editbar_links(self) -> Sequence[BaseLink | LinkGroup] | None: """ A of :class:`onegov.org.elements.LinkGroup` classes. Each of them will be shown in the top editbar, with the group title being the dropdown title. @@ -368,7 +373,7 @@ def login_from_path(self) -> str: auth = Auth.from_request_path(self.request) return self.request.link(auth, name='login') - def export_formatter(self, format: str) -> 'Callable[[object], Any]': + def export_formatter(self, format: str) -> Callable[[object], Any]: """ Returns a formatter function which takes a value and returns the value ready for export. @@ -515,7 +520,7 @@ def file_data_file( def field_download_link( self, - field: 'Field' + field: Field ) -> list[str | None] | str | None: if field.type == 'UploadField': @@ -527,7 +532,7 @@ def field_download_link( ] return None - def field_file(self, field: 'Field') -> list[File | None] | File | None: + def field_file(self, field: Field) -> list[File | None] | File | None: if field.type == 'UploadField': return self.file_data_file(field.data) elif field.type == 'UploadMultipleField': @@ -561,7 +566,7 @@ def get_user_title(self, username: str) -> str: def to_timezone( self, date: datetime, - timezone: 'TzInfoOrName' + timezone: TzInfoOrName ) -> datetime: return to_timezone(date, timezone) @@ -631,7 +636,7 @@ def format_timedelta(self, delta: timedelta) -> str: def format_seconds(self, seconds: float) -> str: return self.format_timedelta(timedelta(seconds=seconds)) - def password_reset_url(self, user: 'User | None') -> str | None: + def password_reset_url(self, user: User | None) -> str | None: if not user: return None @@ -660,7 +665,7 @@ def linkify(self, text: str | None) -> Markup | None: return linkified return linkified.replace('\n', Markup('
')) - def linkify_field(self, field: 'Field', rendered: Markup) -> Markup: + def linkify_field(self, field: Field, rendered: Markup) -> Markup: include = ('TextAreaField', 'StringField', 'EmailField', 'URLField') if field.render_kw: if field.render_kw.get('data-editor') == 'markdown': @@ -754,17 +759,17 @@ def hide_from_robots(self) -> None: return @self.request.after - def respond_with_no_index(response: 'Response') -> None: + def respond_with_no_index(response: Response) -> None: response.headers['X-Robots-Tag'] = 'noindex' class DefaultLayout(Layout, DefaultLayoutMixin): """ The default layout meant for the public facing parts of the site. """ - request: 'OrgRequest' + request: OrgRequest edit_mode: bool - def __init__(self, model: Any, request: 'OrgRequest', + def __init__(self, model: Any, request: OrgRequest, edit_mode: bool = False) -> None: super().__init__(model, request) @@ -792,26 +797,26 @@ def __init__(self, model: Any, request: 'OrgRequest', self.hide_from_robots() - def show_label(self, field: 'Field') -> bool: + def show_label(self, field: Field) -> bool: return True @cached_property - def breadcrumbs(self) -> 'Sequence[Link] | None': + def breadcrumbs(self) -> Sequence[Link] | None: """ Returns the breadcrumbs for the current page. """ return [Link(_('Homepage'), self.homepage_url)] - def exclude_invisible(self, items: 'Iterable[_T]') -> 'Sequence[_T]': + def exclude_invisible(self, items: Iterable[_T]) -> Sequence[_T]: items = self.request.exclude_invisible(items) if not self.request.is_manager: return tuple(i for i in items if getattr(i, 'published', True)) return items @property - def root_pages(self) -> tuple['PageMeta', ...]: + def root_pages(self) -> tuple[PageMeta, ...]: return self.request.root_pages @cached_property - def top_navigation(self) -> 'Sequence[Link] | None': + def top_navigation(self) -> Sequence[Link] | None: return tuple( Link(r.title, r.link(self.request)) for r in self.root_pages ) @@ -860,11 +865,11 @@ class DefaultMailLayout(Layout, DefaultMailLayoutMixin): # type:ignore[misc] """ A special layout for creating HTML E-Mails. """ @cached_property - def base(self) -> 'PageTemplateFile': + def base(self) -> PageTemplateFile: return self.template_loader['mail_layout.pt'] @cached_property - def macros(self) -> 'MacrosLookup': + def macros(self) -> MacrosLookup: return self.template_loader.mail_macros @cached_property @@ -905,7 +910,7 @@ def sortable_url_template(self) -> str: ) ) - def get_breadcrumbs(self, item: 'AdjacencyList') -> 'Iterator[Link]': + def get_breadcrumbs(self, item: AdjacencyList) -> Iterator[Link]: """ Yields the breadcrumbs for the given adjacency list item. """ yield Link(_('Homepage'), self.homepage_url) @@ -918,13 +923,13 @@ def get_breadcrumbs(self, item: 'AdjacencyList') -> 'Iterator[Link]': def get_sidebar( self, type: str | None = None - ) -> 'Iterator[Link | LinkGroup]': + ) -> Iterator[Link | LinkGroup]: """ Yields the sidebar for the given adjacency list item. """ query = self.model.siblings.filter(self.model.__class__.type == type) def filter( - items: 'Iterable[AdjacencyList]' - ) -> 'Sequence[AdjacencyList]': + items: Iterable[AdjacencyList] + ) -> Sequence[AdjacencyList]: items = self.request.exclude_invisible(items) if not self.request.is_manager: @@ -950,14 +955,14 @@ def filter( class AdjacencyListLayout(DefaultLayout, AdjacencyListMixin): - request: 'OrgRequest' + request: OrgRequest class SettingsLayout(DefaultLayout): def __init__( self, model: Any, - request: 'OrgRequest', + request: OrgRequest, setting: str | None = None ) -> None: super().__init__(model, request) @@ -993,11 +998,11 @@ def og_image_source(self) -> str | None: return super().og_image_source @cached_property - def breadcrumbs(self) -> 'Sequence[Link]': + def breadcrumbs(self) -> Sequence[Link]: return tuple(self.get_breadcrumbs(self.model)) @cached_property - def sidebar_links(self) -> 'Sequence[Link | LinkGroup]': + def sidebar_links(self) -> Sequence[Link | LinkGroup]: return tuple(self.get_sidebar(type='topic')) @@ -1013,7 +1018,7 @@ def og_image_source(self) -> str | None: return super().og_image_source @cached_property - def breadcrumbs(self) -> 'Sequence[Link]': + def breadcrumbs(self) -> Sequence[Link]: return tuple(self.get_breadcrumbs(self.model)) @@ -1024,7 +1029,7 @@ class EditorLayout(AdjacencyListLayout): def __init__( self, model: Editor, - request: 'OrgRequest', + request: OrgRequest, site_title: str | None ) -> None: super().__init__(model, request) @@ -1042,14 +1047,12 @@ def breadcrumbs(self) -> list[Link]: class FormEditorLayout(DefaultLayout): - model: ('FormDefinition | FormCollection | SurveyCollection' - '| SurveyDefinition') + model: AnyFormDefinitionOrCollection def __init__( self, - model: ('FormDefinition | FormCollection | SurveyCollection' - '| SurveyDefinition'), - request: 'OrgRequest' + model: AnyFormDefinitionOrCollection, + request: OrgRequest ) -> None: super().__init__(model, request) @@ -1059,12 +1062,12 @@ def __init__( class FormSubmissionLayout(DefaultLayout): - model: 'FormSubmission | FormDefinition' + model: FormSubmission | FormDefinition def __init__( self, - model: 'FormSubmission | FormDefinition', - request: 'OrgRequest', + model: FormSubmission | FormDefinition, + request: OrgRequest, title: str | None = None ) -> None: @@ -1073,7 +1076,7 @@ def __init__( self.title = title or self.form.title @cached_property - def form(self) -> 'FormDefinition': + def form(self) -> FormDefinition: if hasattr(self.model, 'form'): return self.model.form # type:ignore[return-value] else: @@ -1315,12 +1318,12 @@ def editbar_links(self) -> list[Link] | None: class SurveySubmissionLayout(DefaultLayout): - model: 'SurveySubmission | SurveyDefinition' + model: SurveySubmission | SurveyDefinition def __init__( self, - model: 'SurveySubmission | SurveyDefinition', - request: 'OrgRequest', + model: SurveySubmission | SurveyDefinition, + request: OrgRequest, title: str | None = None ) -> None: @@ -1329,7 +1332,7 @@ def __init__( self.title = title or self.form.title @cached_property - def form(self) -> 'SurveyDefinition': + def form(self) -> SurveyDefinition: if hasattr(self.model, 'survey'): return self.model.survey # type:ignore[return-value] else: @@ -1605,9 +1608,9 @@ def editbar_links(self) -> list[Link | LinkGroup]: class TicketLayout(DefaultLayout): - model: 'Ticket' + model: Ticket - def __init__(self, model: 'Ticket', request: 'OrgRequest') -> None: + def __init__(self, model: Ticket, request: OrgRequest) -> None: super().__init__(model, request) self.request.include('timeline') @@ -1743,13 +1746,13 @@ def has_submission_files(self) -> bool: class TicketNoteLayout(DefaultLayout): - ticket: 'Ticket' + ticket: Ticket @overload def __init__( self, - model: 'Ticket', - request: 'OrgRequest', + model: Ticket, + request: OrgRequest, title: str, ticket: None = None ) -> None: ... @@ -1758,17 +1761,17 @@ def __init__( def __init__( self, model: Any, - request: 'OrgRequest', + request: OrgRequest, title: str, - ticket: 'Ticket' + ticket: Ticket ) -> None: ... def __init__( self, model: Any, - request: 'OrgRequest', + request: OrgRequest, title: str, - ticket: 'Ticket | None' = None + ticket: Ticket | None = None ) -> None: super().__init__(model, request) @@ -1794,12 +1797,12 @@ def breadcrumbs(self) -> list[Link]: # ticket attribute, much akin to TicketNoteLayout class TicketChatMessageLayout(DefaultLayout): - model: 'Ticket' + model: Ticket def __init__( self, - model: 'Ticket', - request: 'OrgRequest', + model: Ticket, + request: OrgRequest, internal: bool = False ) -> None: @@ -2051,7 +2054,7 @@ def editbar_links(self) -> list[Link | LinkGroup] | None: class ResourceRecipientsFormLayout(DefaultLayout): - def __init__(self, model: Any, request: 'OrgRequest', title: str) -> None: + def __init__(self, model: Any, request: OrgRequest, title: str) -> None: super().__init__(model, request) self.title = title @@ -2075,9 +2078,9 @@ def breadcrumbs(self) -> list[Link]: class ResourceLayout(DefaultLayout): - model: 'Resource' + model: Resource - def __init__(self, model: 'Resource', request: 'OrgRequest') -> None: + def __init__(self, model: Resource, request: OrgRequest) -> None: super().__init__(model, request) self.request.include('fullcalendar') @@ -2248,7 +2251,7 @@ def breadcrumbs(self) -> list[Link]: @cached_property def editbar_links(self) -> list[Link | LinkGroup]: - def links() -> 'Iterator[Link | LinkGroup]': + def links() -> Iterator[Link | LinkGroup]: if not self.request.is_manager: return @@ -2292,7 +2295,7 @@ def links() -> 'Iterator[Link | LinkGroup]': class EventLayoutMixin: - request: 'OrgRequest' + request: OrgRequest def format_recurrence(self, recurrence: str | None) -> str: """ Returns a human readable version of an RRULE used by us. """ @@ -2322,7 +2325,7 @@ def format_recurrence(self, recurrence: str | None) -> str: return '' - def event_deletable(self, event: 'Event') -> bool: + def event_deletable(self, event: Event) -> bool: tickets = TicketCollection(self.request.session) ticket = tickets.by_handler_id(event.id.hex) return not ticket @@ -2330,8 +2333,8 @@ def event_deletable(self, event: 'Event') -> bool: class OccurrencesLayout(DefaultLayout, EventLayoutMixin): - app: 'OrgApp' - request: 'OrgRequest' + app: OrgApp + request: OrgRequest @property def og_description(self) -> str: @@ -2346,7 +2349,7 @@ def breadcrumbs(self) -> list[Link]: @cached_property def editbar_links(self) -> list[Link | LinkGroup]: - def links() -> 'Iterator[Link | LinkGroup]': + def links() -> Iterator[Link | LinkGroup]: if (self.request.is_admin and self.request.app.org. event_filter_type in ['filters', 'tags_and_filters']): yield Link( @@ -2386,11 +2389,11 @@ def links() -> 'Iterator[Link | LinkGroup]': class OccurrenceLayout(DefaultLayout, EventLayoutMixin): - app: 'OrgApp' - request: 'OrgRequest' - model: 'Occurrence' + app: OrgApp + request: OrgRequest + model: Occurrence - def __init__(self, model: 'Occurrence', request: 'OrgRequest') -> None: + def __init__(self, model: Occurrence, request: OrgRequest) -> None: super().__init__(model, request) self.request.include('monthly-view') @@ -2501,12 +2504,12 @@ def editbar_links(self) -> list[Link | LinkGroup] | None: class EventLayout(EventLayoutMixin, DefaultLayout): - app: 'OrgApp' - request: 'OrgRequest' - model: 'Event' + app: OrgApp + request: OrgRequest + model: Event if TYPE_CHECKING: - def __init__(self, model: 'Event', request: 'OrgRequest') -> None: ... + def __init__(self, model: Event, request: OrgRequest) -> None: ... @cached_property def breadcrumbs(self) -> list[Link]: @@ -2795,9 +2798,9 @@ def editbar_links(self) -> list[Link | LinkGroup] | None: class ImageSetLayout(DefaultLayout): - model: 'ImageSet' + model: ImageSet - def __init__(self, model: 'ImageSet', request: 'OrgRequest') -> None: + def __init__(self, model: ImageSet, request: OrgRequest) -> None: super().__init__(model, request) self.request.include('photoswipe') @@ -2966,7 +2969,7 @@ class UserGroupLayout(DefaultLayout): def __init__(self, model: UserGroup, request: OrgRequest) -> None: ... @cached_property - def collection(self) -> UserGroupCollection['UserGroup']: + def collection(self) -> UserGroupCollection[UserGroup]: return UserGroupCollection(self.request.session) @cached_property @@ -3103,7 +3106,7 @@ def editbar_links(self) -> list[Link | LinkGroup]: class MessageCollectionLayout(DefaultLayout): - def __init__(self, model: Any, request: 'OrgRequest') -> None: + def __init__(self, model: Any, request: OrgRequest) -> None: super().__init__(model, request) self.request.include('timeline') @@ -3117,12 +3120,12 @@ def breadcrumbs(self) -> list[Link]: class DirectoryCollectionLayout(DefaultLayout): - model: 'DirectoryCollection[Any] | DirectoryEntryCollection[Any]' + model: DirectoryCollection[Any] | DirectoryEntryCollection[Any] def __init__( self, - model: 'DirectoryCollection[Any] | DirectoryEntryCollection[Any]', - request: 'OrgRequest' + model: DirectoryCollection[Any] | DirectoryEntryCollection[Any], + request: OrgRequest ) -> None: super().__init__(model, request) @@ -3164,8 +3167,8 @@ def editbar_links(self) -> list[Link | LinkGroup] | None: class DirectoryEntryMixin: - request: 'OrgRequest' - model: 'ExtendedDirectoryEntry | ExtendedDirectoryEntryCollection' + request: OrgRequest + model: ExtendedDirectoryEntry | ExtendedDirectoryEntryCollection custom_body_attributes: dict[str, Any] def init_markers(self) -> None: @@ -3179,7 +3182,7 @@ def init_markers(self) -> None: self.directory.marker_icon.encode('unicode-escape')[2:]) @property - def directory(self) -> 'ExtendedDirectory': + def directory(self) -> ExtendedDirectory: return self.model.directory @cached_property @@ -3188,19 +3191,19 @@ def thumbnail_field_id(self) -> str | None: return as_internal_id(thumbnail) return None - def thumbnail_file_id(self, entry: 'ExtendedDirectoryEntry') -> str | None: + def thumbnail_file_id(self, entry: ExtendedDirectoryEntry) -> str | None: thumbnail = self.thumbnail_field_id if not thumbnail: return None return (entry.values.get(thumbnail) or {}).get('data', '').lstrip('@') - def thumbnail_link(self, entry: 'ExtendedDirectoryEntry') -> str | None: + def thumbnail_link(self, entry: ExtendedDirectoryEntry) -> str | None: file_id = self.thumbnail_file_id(entry) return self.request.class_link( File, {'id': file_id}, name='thumbnail' ) if file_id else None - def thumbnail_file(self, entry: 'ExtendedDirectoryEntry') -> File | None: + def thumbnail_file(self, entry: ExtendedDirectoryEntry) -> File | None: file_id = self.thumbnail_file_id(entry) if not file_id: return None @@ -3209,13 +3212,13 @@ def thumbnail_file(self, entry: 'ExtendedDirectoryEntry') -> File | None: class DirectoryEntryCollectionLayout(DefaultLayout, DirectoryEntryMixin): - request: 'OrgRequest' + request: OrgRequest model: ExtendedDirectoryEntryCollection def __init__( self, model: ExtendedDirectoryEntryCollection, - request: 'OrgRequest' + request: OrgRequest ) -> None: super().__init__(model, request) @@ -3249,7 +3252,7 @@ def editbar_links(self) -> list[Link | LinkGroup]: attrs={'class': 'export-link'} ) - def links() -> 'Iterator[Link | LinkGroup]': + def links() -> Iterator[Link | LinkGroup]: qr_link = None if self.request.is_admin: yield Link( @@ -3389,7 +3392,7 @@ def publication_filter_title(self) -> str: return f'{default_title}: {self.request.translate(_("Choose filter"))}' @property - def publication_links(self) -> 'Iterator[Link]': + def publication_links(self) -> Iterator[Link]: return ( self.get_pub_link(text, filter_kw) for filter_kw, text in self.publication_filters.items() @@ -3397,19 +3400,19 @@ def publication_links(self) -> 'Iterator[Link]': class DirectoryEntryLayout(DefaultLayout, DirectoryEntryMixin): - request: 'OrgRequest' - model: 'ExtendedDirectoryEntry' + request: OrgRequest + model: ExtendedDirectoryEntry def __init__( self, - model: 'ExtendedDirectoryEntry', - request: 'OrgRequest' + model: ExtendedDirectoryEntry, + request: OrgRequest ) -> None: super().__init__(model, request) self.init_markers() - def show_label(self, field: 'Field') -> bool: + def show_label(self, field: Field) -> bool: return field.id not in self.model.hidden_label_fields @cached_property @@ -3430,7 +3433,7 @@ def thumbnail_field_ids(self) -> list[str]: def field_download_link( self, - field: 'Field' + field: Field ) -> list[str | None] | str | None: url = super().field_download_link(field) @@ -3512,7 +3515,7 @@ def editbar_links(self) -> list[Link | LinkGroup] | None: class PublicationLayout(DefaultLayout): - def __init__(self, model: Any, request: 'OrgRequest') -> None: + def __init__(self, model: Any, request: OrgRequest) -> None: super().__init__(model, request) self.request.include('filedigest') @@ -3537,7 +3540,7 @@ def breadcrumbs(self) -> list[Link]: class GeneralFileCollectionLayout(DefaultLayout): - def __init__(self, model: Any, request: 'OrgRequest') -> None: + def __init__(self, model: Any, request: OrgRequest) -> None: request.include('common') request.include('upload') request.include('prompt') @@ -3546,7 +3549,7 @@ def __init__(self, model: Any, request: 'OrgRequest') -> None: class ImageFileCollectionLayout(DefaultLayout): - def __init__(self, model: Any, request: 'OrgRequest') -> None: + def __init__(self, model: Any, request: OrgRequest) -> None: request.include('common') request.include('upload') request.include('editalttext') diff --git a/src/onegov/org/locale/de_CH/LC_MESSAGES/onegov.org.po b/src/onegov/org/locale/de_CH/LC_MESSAGES/onegov.org.po index fcb871c6ea..2fd7e443f8 100644 --- a/src/onegov/org/locale/de_CH/LC_MESSAGES/onegov.org.po +++ b/src/onegov/org/locale/de_CH/LC_MESSAGES/onegov.org.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE 1.0\n" -"POT-Creation-Date: 2024-11-25 19:53+0100\n" +"POT-Creation-Date: 2025-01-08 16:47+0100\n" "PO-Revision-Date: 2022-03-15 10:21+0100\n" "Last-Translator: Marc Sommerhalder \n" "Language-Team: German\n" @@ -1020,6 +1020,15 @@ msgstr "Grosse Bilder" msgid "Grid layout" msgstr "Raster" +msgid "By filename" +msgstr "Nach Dateiname" + +msgid "By caption" +msgstr "Nach Beschreibung" + +msgid "By last change" +msgstr "Nach Zeitpunkt der letzten Änderung" + msgid "Show images on homepage" msgstr "Bilder auf der Startseite zeigen" @@ -1684,6 +1693,12 @@ msgstr "Analytics Code" msgid "JavaScript for web statistics support" msgstr "JavaScript für Web-Statistik" +msgid "Analytics URL" +msgstr "" + +msgid "URL pointing to the analytics page" +msgstr "" + msgid "Cantonal holidays" msgstr "Kantonale Feiertage" @@ -2765,9 +2780,6 @@ msgstr "" msgid "Delete content" msgstr "Inhalt löschen" -msgid "Photo album. Will be shown at the end of content." -msgstr "Fotoalbum. Wird am Ende des Inhalts angezeigt." - msgid "Photo album" msgstr "Fotoalbum" @@ -2946,8 +2958,8 @@ msgstr "Die Absage von ${title} kann nicht rückgängig gemacht werden." msgid "Reject reservation" msgstr "Reservation absagen" -#. Used in sentence: "${event} published." #. +#. Used in sentence: "${event} published." msgid "Event" msgstr "Veranstaltung" @@ -6183,6 +6195,9 @@ msgstr "Ein Konto wurde für Sie erstellt" msgid "The user was created successfully" msgstr "Der Benutzer wurde erfolgreich erstellt" +#~ msgid "Photo album. Will be shown at the end of content." +#~ msgstr "Fotoalbum. Wird am Ende des Inhalts angezeigt." + #~ msgid "Include logo in newsletter" #~ msgstr "Logo im Newsletter anzeigen" diff --git a/src/onegov/org/locale/fr_CH/LC_MESSAGES/onegov.org.po b/src/onegov/org/locale/fr_CH/LC_MESSAGES/onegov.org.po index c4a44bab91..579f27fa6f 100644 --- a/src/onegov/org/locale/fr_CH/LC_MESSAGES/onegov.org.po +++ b/src/onegov/org/locale/fr_CH/LC_MESSAGES/onegov.org.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE 1.0\n" -"POT-Creation-Date: 2024-11-25 19:53+0100\n" +"POT-Creation-Date: 2025-01-08 16:47+0100\n" "PO-Revision-Date: 2022-03-15 10:50+0100\n" "Last-Translator: Marc Sommerhalder \n" "Language-Team: French\n" @@ -1020,6 +1020,15 @@ msgstr "Images de taille normale" msgid "Grid layout" msgstr "Mise en page en grille" +msgid "By filename" +msgstr "Par nom de fichier" + +msgid "By caption" +msgstr "Par légende" + +msgid "By last change" +msgstr "Par date de dernière modification" + msgid "Show images on homepage" msgstr "Montrer les images sur la page d'accueil" @@ -1685,6 +1694,12 @@ msgstr "Code Analytics" msgid "JavaScript for web statistics support" msgstr "JavaScript pour l'assistance en matière de statistiques web" +msgid "Analytics URL" +msgstr "" + +msgid "URL pointing to the analytics page" +msgstr "" + msgid "Cantonal holidays" msgstr "Jours fériés cantonaux" @@ -2766,9 +2781,6 @@ msgstr "" msgid "Delete content" msgstr "Supprimer le contenu" -msgid "Photo album. Will be shown at the end of content." -msgstr "Album photo. Sera affiché à la fin du contenu." - msgid "Photo album" msgstr "Album photo" @@ -2947,8 +2959,8 @@ msgstr "Refuser ${title} est irréversible." msgid "Reject reservation" msgstr "Refuser la réservation" -#. Used in sentence: "${event} published." #. +#. Used in sentence: "${event} published." msgid "Event" msgstr "Événement" @@ -3302,8 +3314,8 @@ msgid "" "filled-out form." msgstr "" "Veuillez vérifier vos données et appuyez sur « Compléter » pour finaliser le " -"processus. S'il y a quelque chose que vous souhaitez modifier, cliquez sur « " -"Modifier » pour retourner sur le formulaire complété." +"processus. S'il y a quelque chose que vous souhaitez modifier, cliquez sur " +"« Modifier » pour retourner sur le formulaire complété." msgid "" "The image shown in the list view is a square. To have your image shown fully " @@ -6202,3 +6214,6 @@ msgstr "Un compte a été créé pour vous" msgid "The user was created successfully" msgstr "L'utilisateur a bien été créé" + +#~ msgid "Photo album. Will be shown at the end of content." +#~ msgstr "Album photo. Sera affiché à la fin du contenu." diff --git a/src/onegov/org/locale/it_CH/LC_MESSAGES/onegov.org.po b/src/onegov/org/locale/it_CH/LC_MESSAGES/onegov.org.po index 02abe111f6..a71a78e1cb 100644 --- a/src/onegov/org/locale/it_CH/LC_MESSAGES/onegov.org.po +++ b/src/onegov/org/locale/it_CH/LC_MESSAGES/onegov.org.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2024-11-25 19:53+0100\n" +"POT-Creation-Date: 2025-01-08 16:47+0100\n" "PO-Revision-Date: 2022-03-15 10:52+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -1022,6 +1022,15 @@ msgstr "Immagini a grandezza naturale" msgid "Grid layout" msgstr "Disposizione a griglia" +msgid "By filename" +msgstr "Per nome del file" + +msgid "By caption" +msgstr "Per didascalia" + +msgid "By last change" +msgstr "Per data dell'ultima modifica" + msgid "Show images on homepage" msgstr "Mostra le immagini sulla pagina principale" @@ -1687,6 +1696,12 @@ msgstr "Codice Analytics" msgid "JavaScript for web statistics support" msgstr "JavaScript per il supporto delle statistiche web" +msgid "Analytics URL" +msgstr "" + +msgid "URL pointing to the analytics page" +msgstr "" + msgid "Cantonal holidays" msgstr "Festività cantonali" @@ -2772,9 +2787,6 @@ msgstr "" msgid "Delete content" msgstr "Cancellare il contenuto" -msgid "Photo album. Will be shown at the end of content." -msgstr "Album fotografico. Sarà mostrato alla fine del contenuto." - msgid "Photo album" msgstr "Album fotografico" @@ -2953,8 +2965,8 @@ msgstr "Il rifiuto di ${title} non può essere annullato." msgid "Reject reservation" msgstr "Rifiuta prenotazione" -#. Used in sentence: "${event} published." #. +#. Used in sentence: "${event} published." msgid "Event" msgstr "Evento" @@ -6189,3 +6201,6 @@ msgstr "È stato creato un account per te" msgid "The user was created successfully" msgstr "Utente creato correttamente" + +#~ msgid "Photo album. Will be shown at the end of content." +#~ msgstr "Album fotografico. Sarà mostrato alla fine del contenuto." diff --git a/src/onegov/org/mail.py b/src/onegov/org/mail.py index f67cccb065..9cf3c4e18d 100644 --- a/src/onegov/org/mail.py +++ b/src/onegov/org/mail.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.templates import render_template from onegov.org.layout import DefaultMailLayout @@ -33,10 +35,10 @@ class AllEmailArguments(EmailArgumentsWithCategory): def send_html_mail( - request: 'OrgRequest', + request: OrgRequest, template: str, content: dict[str, Any], - **kwargs: 'Unpack[EmailArgumentsWithCategory]' + **kwargs: Unpack[EmailArgumentsWithCategory] ) -> None: """" Sends an email rendered from the given template. @@ -70,10 +72,10 @@ def send_html_mail( def send_transactional_html_mail( - request: 'OrgRequest', + request: OrgRequest, template: str, content: dict[str, Any], - **kwargs: 'Unpack[EmailArguments]' + **kwargs: Unpack[EmailArguments] ) -> None: send_html_mail( @@ -86,10 +88,10 @@ def send_transactional_html_mail( def send_marketing_html_mail( - request: 'OrgRequest', + request: OrgRequest, template: str, content: dict[str, Any], - **kwargs: 'Unpack[EmailArguments]' + **kwargs: Unpack[EmailArguments] ) -> None: send_html_mail( @@ -102,17 +104,17 @@ def send_marketing_html_mail( def send_ticket_mail( - request: 'OrgRequest', + request: OrgRequest, template: str, subject: str, - receivers: 'Sequence[Address | str]', - ticket: 'Ticket', + receivers: Sequence[Address | str], + ticket: Ticket, content: dict[str, Any] | None = None, force: bool = False, send_self: bool = False, - bcc: 'SequenceOrScalar[Address | str]' = (), - attachments: 'Iterable[Attachment | StrPath]' = (), - **kwargs: 'Unpack[TicketEmailExtraArguments]' + bcc: SequenceOrScalar[Address | str] = (), + attachments: Iterable[Attachment | StrPath] = (), + **kwargs: Unpack[TicketEmailExtraArguments] ) -> None: org = request.app.org diff --git a/src/onegov/org/management.py b/src/onegov/org/management.py index ec89523c4e..f416e2db44 100644 --- a/src/onegov/org/management.py +++ b/src/onegov/org/management.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re import time from collections import defaultdict @@ -37,7 +39,7 @@ class LinkMigration(ModelsWithLinksMixin): def __init__( self, - request: 'OrgRequest', + request: OrgRequest, old_uri: str, new_uri: str = '' ) -> None: @@ -57,7 +59,7 @@ def __init__( def migrate_url( self, item: object, - fields: 'Iterable[str]', + fields: Iterable[str], test: bool = False, group_by: str | None = None, count_obj: dict[str, dict[str, int]] | None = None @@ -128,8 +130,8 @@ class PageNameChange(ModelsWithLinksMixin): def __init__( self, - request: 'OrgRequest', - page: 'Page', + request: OrgRequest, + page: Page, new_name: str ) -> None: @@ -141,10 +143,10 @@ def __init__( self.new_name = new_name @property - def subpages(self) -> list['Page']: + def subpages(self) -> list[Page]: pages: list[Page] = [] - def add(page: 'Page') -> None: + def add(page: Page) -> None: nonlocal pages pages.append(page) for child in page.children: @@ -189,7 +191,7 @@ def run() -> int: return run() @classmethod - def from_form(cls, model: 'Page', form: 'Form') -> 'Self': + def from_form(cls, model: Page, form: Form) -> Self: return cls(form.request, model, form['name'].data) # type:ignore @@ -221,7 +223,7 @@ class Statistic(NamedTuple): def __init__( self, - request: 'OrgRequest', + request: OrgRequest, link_type: Literal['internal', 'external', ''] | None = None, total_timout: float = 30 ) -> None: @@ -253,14 +255,14 @@ def external_only(self) -> bool: def internal_link(self, url: str) -> bool: return self.domain in url - def filter_urls(self, urls: 'Sequence[str]') -> 'Sequence[str]': + def filter_urls(self, urls: Sequence[str]) -> Sequence[str]: if self.external_only: return tuple(url for url in urls if not self.internal_link(url)) if self.internal_only: return tuple(url for url in urls if self.internal_link(url)) return urls - def find_urls(self) -> 'Iterator[tuple[str, str, Sequence[str]]]': + def find_urls(self) -> Iterator[tuple[str, str, Sequence[str]]]: for entries in self.site_collection.get().values(): for entry in entries: urls = [] @@ -287,12 +289,12 @@ def find_urls(self) -> 'Iterator[tuple[str, str, Sequence[str]]]': self.filter_urls(urls) ) - def url_list_generator(self) -> 'Iterator[LinkCheck]': + def url_list_generator(self) -> Iterator[LinkCheck]: for name, model_link, urls in self.find_urls(): for url in urls: yield LinkCheck(name, model_link, url) - def unhealthy_urls(self) -> tuple[Statistic, 'Sequence[LinkCheck]']: + def unhealthy_urls(self) -> tuple[Statistic, Sequence[LinkCheck]]: """ We check the urls in the backend, unless they are internal. In that case, we can not do that since we do not have async support. Otherwise returns the LinkChecks with empty statistics for use in diff --git a/src/onegov/org/models/__init__.py b/src/onegov/org/models/__init__.py index 08d1a99e77..7998d0d95d 100644 --- a/src/onegov/org/models/__init__.py +++ b/src/onegov/org/models/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.org.models.atoz import AtoZ from onegov.org.models.clipboard import Clipboard from onegov.org.models.dashboard import Boardlet diff --git a/src/onegov/org/models/atoz.py b/src/onegov/org/models/atoz.py index 1e6547881e..92528f3c97 100644 --- a/src/onegov/org/models/atoz.py +++ b/src/onegov/org/models/atoz.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import OrderedDict from itertools import groupby from unidecode import unidecode @@ -14,7 +16,7 @@ class AtoZ(Generic[_T]): - def __init__(self, request: 'OrgRequest') -> None: + def __init__(self, request: OrgRequest) -> None: self.request = request def sortkey(self, item: _T) -> str: @@ -33,5 +35,5 @@ def get_items_by_letter(self) -> dict[str, tuple[_T, ...]]: def get_title(self, item: _T) -> str: raise NotImplementedError - def get_items(self) -> 'Sequence[_T]': + def get_items(self) -> Sequence[_T]: raise NotImplementedError diff --git a/src/onegov/org/models/clipboard.py b/src/onegov/org/models/clipboard.py index c4889d5ec2..fff0b87d47 100644 --- a/src/onegov/org/models/clipboard.py +++ b/src/onegov/org/models/clipboard.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property @@ -17,7 +19,7 @@ class Clipboard: """ - def __init__(self, request: 'OrgRequest', token: str) -> None: + def __init__(self, request: OrgRequest, token: str) -> None: self.request = request self.token = token @@ -41,14 +43,14 @@ def store_in_session(self) -> None: self.request.browser_session['clipboard_url'] = self.url @classmethod - def from_url(cls, request: 'OrgRequest', url: str) -> 'Self': + def from_url(cls, request: OrgRequest, url: str) -> Self: return cls( request, request.new_url_safe_token({'url': url}, salt='clipboard') ) @classmethod - def from_session(cls, request: 'OrgRequest') -> 'Self': + def from_session(cls, request: OrgRequest) -> Self: return cls( request, request.new_url_safe_token( diff --git a/src/onegov/org/models/dashboard.py b/src/onegov/org/models/dashboard.py index f2a8d6fda0..904ce85320 100644 --- a/src/onegov/org/models/dashboard.py +++ b/src/onegov/org/models/dashboard.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from attr import attrs from itertools import groupby @@ -10,7 +12,7 @@ class Dashboard: - def __init__(self, request: 'OrgRequest') -> None: + def __init__(self, request: OrgRequest) -> None: self.request = request @property @@ -19,7 +21,7 @@ def is_available(self) -> bool: return self.request.app.config.boardlets_registry and True or False - def boardlets(self) -> list[tuple['Boardlet', ...]]: + def boardlets(self) -> list[tuple[Boardlet, ...]]: """ Returns the boardlets, grouped/ordered by their order tuple. """ instances = [] @@ -57,7 +59,7 @@ def __init__( self, name: str, order: tuple[int, int], - request: 'OrgRequest' + request: OrgRequest ) -> None: self.name = name self.order = order @@ -72,7 +74,7 @@ def title(self) -> str: raise NotImplementedError() @property - def facts(self) -> 'Iterator[BoardletFact]': + def facts(self) -> Iterator[BoardletFact]: """ Yields facts. (:class:`BoardletFact` instances)""" raise NotImplementedError() diff --git a/src/onegov/org/models/directory.py b/src/onegov/org/models/directory.py index 48043d062c..18ba2a449a 100644 --- a/src/onegov/org/models/directory.py +++ b/src/onegov/org/models/directory.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate from copy import copy @@ -62,7 +64,7 @@ class ExtendedDirectoryEntryForm(DirectoryEntryForm): @property def submitter_meta(self) -> Mapping[str, str | None]: ... @property - def target(self) -> 'ExtendedDirectoryEntry | None': ... + def target(self) -> ExtendedDirectoryEntry | None: ... def is_different(self, field: Field) -> bool: ... def ensure_changes(self) -> bool | None: ... def ensure_publication_start_end(self) -> bool | None: ... @@ -78,10 +80,10 @@ class DirectorySubmissionAction: def __init__( self, - session: 'Session', - directory_id: 'UUID', + session: Session, + directory_id: UUID, action: str, - submission_id: 'UUID' + submission_id: UUID ) -> None: self.session = session @@ -115,7 +117,7 @@ def ticket(self) -> Ticket | None: def send_mail_if_enabled( self, - request: 'OrgRequest', + request: OrgRequest, subject: str, template: str ) -> None: @@ -153,7 +155,7 @@ def is_change(self) -> bool: return ('change-request' in self.submission.extensions) # type:ignore[union-attr] - def execute(self, request: 'OrgRequest') -> None: + def execute(self, request: OrgRequest) -> None: assert self.valid assert self.directory is not None assert self.ticket is not None @@ -163,7 +165,7 @@ def execute(self, request: 'OrgRequest') -> None: return getattr(self, self.action)(request) - def adopt(self, request: 'OrgRequest') -> None: + def adopt(self, request: OrgRequest) -> None: assert self.directory is not None assert self.submission is not None assert self.ticket is not None @@ -211,7 +213,7 @@ def adopt(self, request: 'OrgRequest') -> None: def create_new_entry( self, - request: 'OrgRequest', + request: OrgRequest, data: dict[str, Any] ) -> DirectoryEntry: @@ -235,7 +237,7 @@ def create_new_entry( def apply_change_request( self, - request: 'OrgRequest', + request: OrgRequest, data: dict[str, Any] ) -> DirectoryEntry: @@ -300,7 +302,7 @@ def apply_change_request( return entry - def reject(self, request: 'OrgRequest') -> None: + def reject(self, request: OrgRequest) -> None: assert self.ticket is not None # be idempotent @@ -335,7 +337,7 @@ def reject(self, request: 'OrgRequest') -> None: DirectoryMessage.create( self.directory, self.ticket, request, 'change-rejected') - def withdraw_rejection(self, request: 'OrgRequest') -> None: + def withdraw_rejection(self, request: OrgRequest) -> None: assert self.ticket is not None # be idempotent @@ -404,7 +406,7 @@ class ExtendedDirectory(Directory, AccessExtension, Extendable, currency: dict_property[str | None] = content_property() minimum_price_total: dict_property[float | None] = meta_property() - payment_method: dict_property['PaymentMethod | None'] = meta_property() + payment_method: dict_property[PaymentMethod | None] = meta_property() search_widget_config: dict_property[dict[str, Any] | None] search_widget_config = content_property() @@ -429,14 +431,14 @@ def es_public(self) -> bool: if TYPE_CHECKING: def extend_form_class( # type:ignore[override] self, - form_class: type['DirectoryEntryForm'], # type:ignore[override] + form_class: type[DirectoryEntryForm], # type:ignore[override] extensions: Collection[str] - ) -> type['ExtendedDirectoryEntryForm']: ... + ) -> type[ExtendedDirectoryEntryForm]: ... def form_class_for_submissions( self, change_request: bool = False - ) -> type['ExtendedDirectoryEntryForm']: + ) -> type[ExtendedDirectoryEntryForm]: """ Generates the form_class used for user submissions and change requests. The resulting form always includes a submitter field and all fields. When doing a change request, removes input required validators @@ -467,7 +469,7 @@ def actual_price(self) -> Price | None: def submission_action( self, action: Literal['adopt', 'reject', 'withdraw_rejection'], - submission_id: 'UUID' + submission_id: UUID ) -> DirectorySubmissionAction: return DirectorySubmissionAction( @@ -537,7 +539,7 @@ def contact(self) -> Markup | None: return None @property - def content_fields(self) -> tuple['Field', ...] | None: + def content_fields(self) -> tuple[Field, ...] | None: content_config = { as_internal_id(k) for k in self.display_config.get('content', ()) @@ -569,9 +571,9 @@ def __init__( directory: ExtendedDirectory, # FIXME: We should probably disallow the type argument here type: Literal['extended'] = 'extended', - keywords: 'Mapping[str, list[str]] | None' = None, + keywords: Mapping[str, list[str]] | None = None, page: int = 0, - search_widget: 'ExtendedDirectorySearchWidget | None' = None, + search_widget: ExtendedDirectorySearchWidget | None = None, published_only: bool = False, past_only: bool = False, upcoming_only: bool = False @@ -585,7 +587,7 @@ def __init__( if TYPE_CHECKING: directory: ExtendedDirectory - def query(self) -> 'Query[ExtendedDirectoryEntry]': + def query(self) -> Query[ExtendedDirectoryEntry]: query = super().query() if self.published_only: query = query.filter( diff --git a/src/onegov/org/models/editor.py b/src/onegov/org/models/editor.py index 3cf1e9d331..ebe817dc81 100644 --- a/src/onegov/org/models/editor.py +++ b/src/onegov/org/models/editor.py @@ -1,4 +1,5 @@ """ Contains the model describing the page editor. """ +from __future__ import annotations from typing import overload, Literal, TYPE_CHECKING @@ -23,7 +24,7 @@ class Editor: @overload def __init__( self, - action: 'PageActionWithoutPage', + action: PageActionWithoutPage, page: None, trait: str ) -> None: ... @@ -31,8 +32,8 @@ def __init__( @overload def __init__( self, - action: 'PageAction', - page: 'TraitInfo', + action: PageAction, + page: TraitInfo, trait: str | None = None ) -> None: ... @@ -46,9 +47,9 @@ def __init__( def __init__( self, - action: 'PageAction', + action: PageAction, # NOTE: We would like this to be (Page & TraitInfo) | None - page: 'TraitInfo | None', + page: TraitInfo | None, trait: str | None = None ) -> None: """ The editor is defined by an action and a page/context. @@ -83,7 +84,7 @@ def __init__( self.trait = trait @staticmethod - def is_supported_action(action: str) -> 'TypeGuard[PageAction]': + def is_supported_action(action: str) -> TypeGuard[PageAction]: """ Returns True if the given action is supported. """ return action in { 'new', 'new-root', 'paste', 'edit', 'delete', 'change-url', diff --git a/src/onegov/org/models/export.py b/src/onegov/org/models/export.py index 8994206364..f8a861fb4e 100644 --- a/src/onegov/org/models/export.py +++ b/src/onegov/org/models/export.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any, TYPE_CHECKING if TYPE_CHECKING: from collections.abc import Iterable, Iterator @@ -11,18 +13,18 @@ class ExportCollection: def __init__( self, - app: 'OrgApp', + app: OrgApp, registry: str = 'export_registry' ) -> None: self.registry = getattr(app.config, registry) - def by_id(self, id: object) -> 'Export | None': + def by_id(self, id: object) -> Export | None: return self.registry.get(id) def exports_for_current_user( self, - request: 'OrgRequest' - ) -> 'Iterator[Export]': + request: OrgRequest + ) -> Iterator[Export]: app = request.app for export in self.registry.values(): @@ -41,7 +43,7 @@ def __getattr__(self, name: str) -> Any: ... def run( self, - form: 'Form', - session: 'Session' - ) -> 'Iterable[Iterable[tuple[Any, Any]]]': + form: Form, + session: Session + ) -> Iterable[Iterable[tuple[Any, Any]]]: raise NotImplementedError diff --git a/src/onegov/org/models/extensions.py b/src/onegov/org/models/extensions.py index 8fc8801c6f..d4c29e794a 100644 --- a/src/onegov/org/models/extensions.py +++ b/src/onegov/org/models/extensions.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re import json @@ -81,7 +83,7 @@ class ContentExtension: content: Column[dict[str, Any]] @property - def content_extensions(self) -> 'Iterator[type[ContentExtension]]': + def content_extensions(self) -> Iterator[type[ContentExtension]]: """ Returns all base classes of the current class which themselves have ``ContentExtension`` as baseclass. @@ -92,10 +94,10 @@ def content_extensions(self) -> 'Iterator[type[ContentExtension]]': def with_content_extensions( self, - form_class: type['FormT'], - request: 'OrgRequest', - extensions: 'Iterable[type[SupportsExtendForm]] | None' = None - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest, + extensions: Iterable[type[SupportsExtendForm]] | None = None + ) -> type[FormT]: """ Takes the given form and request and extends the form with all content extensions in the order in which they occur in the base class list. @@ -113,9 +115,9 @@ class list. def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: """ Must be implemented by each ContentExtension. Takes the form class without extension and adds the required fields to it. @@ -146,9 +148,9 @@ class AccessExtension(ContentExtension): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: access_choices = [ ('public', _('Public')), @@ -204,9 +206,9 @@ class CoordinatesExtension(ContentExtension, CoordinatesMixin): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: return CoordinatesFormExtension(form_class).create() @@ -220,9 +222,9 @@ class VisibleOnHomepageExtension(ContentExtension): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: # do not show on root pages if self.parent_id is None: # type:ignore[attr-defined] @@ -258,14 +260,14 @@ def contact_html(self) -> Markup | None: return None return to_html_ul(self.contact, convert_dashes=True, with_title=True) - def get_contact_html(self, request: 'OrgRequest') -> Markup | None: + def get_contact_html(self, request: OrgRequest) -> Markup | None: return self.contact_html def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: class ContactPageForm(form_class): # type:ignore contact = TextAreaField( @@ -298,7 +300,7 @@ class InheritableContactExtension(ContactExtensionBase, ContentExtension): # TODO: If we end up calling this more than once per request # we may want to cache this - def get_contact_html(self, request: 'OrgRequest') -> Markup | None: + def get_contact_html(self, request: OrgRequest) -> Markup | None: if self.inherit_contact: if self.contact_inherited_from is None: return None @@ -311,9 +313,9 @@ def get_contact_html(self, request: 'OrgRequest') -> Markup | None: def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: query = PageCollection(request.session).query() query = query.filter(Page.type == 'topic') @@ -381,9 +383,9 @@ class ContactHiddenOnPageExtension(ContentExtension): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: class ContactHiddenOnPageForm(form_class): # type:ignore hide_contact = BooleanField( @@ -405,9 +407,9 @@ class PeopleShownOnMainPageExtension(ContentExtension): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: class PeopleShownOnMainPageForm(form_class): # type:ignore show_people_on_main_page = BooleanField( @@ -429,9 +431,9 @@ class NewsletterExtension(ContentExtension): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: class NewsletterSettingsForm(form_class): # type:ignore text_in_newsletter = BooleanField( @@ -459,7 +461,7 @@ class PersonLinkExtension(ContentExtension): western_name_order: dict_property[bool] = content_property(default=False) @property - def people(self) -> list['PersonWithFunction'] | None: + def people(self) -> list[PersonWithFunction] | None: """ Returns the people linked to this content or None. The context specific function is temporarily stored on the @@ -493,7 +495,7 @@ def people(self) -> list['PersonWithFunction'] | None: return result - def get_selectable_people(self, request: 'OrgRequest') -> list[Person]: + def get_selectable_people(self, request: OrgRequest) -> list[Person]: """ Returns a list of people which may be linked. """ query = PersonCollection(request.session).query() @@ -528,7 +530,7 @@ def move_person( assert subject != target assert self.content.get('people') - def new_order() -> 'Iterator[tuple[str, tuple[str, bool]]]': + def new_order() -> Iterator[tuple[str, tuple[str, bool]]]: subject_function, show_subject_function = ( self.get_person_function_by_id(subject)) @@ -548,10 +550,10 @@ def new_order() -> 'Iterator[tuple[str, tuple[str, bool]]]': self.content['people'] = list(new_order()) def extend_form( - self: '_ExtendedWithPersonLinkT', - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + self: _ExtendedWithPersonLinkT, + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: selectable_people = self.get_selectable_people(request) if not selectable_people: @@ -560,7 +562,7 @@ def extend_form( selected = dict((self.content or {}).get('people', [])) - def choice(person: Person) -> '_Choice': + def choice(person: Person) -> _Choice: if self.western_name_order: name = f'{person.first_name} {person.last_name}' else: @@ -633,9 +635,9 @@ def is_ordered_people(self, people: list[tuple[str, Any]]) -> bool: def process( self, - formdata: '_MultiDictLikeWithGetlist | None', + formdata: _MultiDictLikeWithGetlist | None, data: Any = unset_value, - extra_filters: 'Sequence[_Filter] | None' = None + extra_filters: Sequence[_Filter] | None = None ) -> None: # FIXME: I'm not quite sure why we need to do this @@ -735,13 +737,13 @@ class ResourceValidationExtension(ContentExtension): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: class WithResourceValidation(form_class): # type:ignore - def validate_title(self, field: 'Field') -> None: + def validate_title(self, field: Field) -> None: existing = ( self.request.session.query(Resource). filter_by(name=normalize_for_url(field.data)).first() @@ -758,9 +760,9 @@ class PublicationExtension(ContentExtension): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: return PublicationFormExtension(form_class).create() @@ -770,9 +772,9 @@ class HoneyPotExtension(ContentExtension): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: class HoneyPotForm(form_class): # type:ignore @@ -793,9 +795,9 @@ class ImageExtension(ContentExtension): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: class PageImageForm(form_class): # type:ignore # pass label by keyword to give the News model access @@ -829,11 +831,11 @@ class PageImageForm(form_class): # type:ignore def _files_observer( - self: 'GeneralFileLinkExtension', + self: GeneralFileLinkExtension, files: list[File], meta: set[str], - publication_start: 'datetime | None' = None, - publication_end: 'datetime | None' = None + publication_start: datetime | None = None, + publication_end: datetime | None = None ) -> None: # mainly we want to observe changes to the linked files # but when the publication or access changes we may need @@ -860,7 +862,7 @@ def _files_observer( def _content_file_link_observer( - self: 'GeneralFileLinkExtension', + self: GeneralFileLinkExtension, content: set[str] ) -> None: # we don't automatically unlink files removed from the text to keep @@ -961,9 +963,9 @@ def content_file_link_observer(cls): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: class GeneralFileForm(form_class): # type:ignore files = UploadOrSelectExistingMultipleFilesField( @@ -971,7 +973,7 @@ class GeneralFileForm(form_class): # type:ignore fieldset=_('Documents') ) - def populate_obj(self, obj: 'GeneralFileLinkExtension', + def populate_obj(self, obj: GeneralFileLinkExtension, *args: Any, **kwargs: Any) -> None: super().populate_obj(obj, *args, **kwargs) @@ -1008,9 +1010,9 @@ class SidebarLinksExtension(ContentExtension): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: class SidebarLinksForm(form_class): # type:ignore @@ -1031,7 +1033,7 @@ def on_request(self) -> None: if not self.sidepanel_links.data: self.sidepanel_links.data = self.links_to_json(None) - def process_obj(self, obj: 'SidebarLinksExtension') -> None: + def process_obj(self, obj: SidebarLinksExtension) -> None: super().process_obj(obj) if not obj.sidepanel_links: self.sidepanel_links.data = self.links_to_json(None) @@ -1042,7 +1044,7 @@ def process_obj(self, obj: 'SidebarLinksExtension') -> None: def populate_obj( self, - obj: 'SidebarLinksExtension', + obj: SidebarLinksExtension, *args: Any, **kwargs: Any ) -> None: super().populate_obj(obj, *args, **kwargs) @@ -1077,7 +1079,7 @@ def json_to_links( def links_to_json( self, - links: 'Sequence[tuple[str | None, str | None]] | None' + links: Sequence[tuple[str | None, str | None]] | None ) -> str: sidepanel_links = links or [] @@ -1112,9 +1114,9 @@ class DeletableContentExtension(ContentExtension): def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: class DeletableContentForm(form_class): # type:ignore delete_when_expired = BooleanField( @@ -1136,7 +1138,7 @@ class InlinePhotoAlbumExtension(ContentExtension): photo_album_id: dict_property[str | None] = content_property(default=None) @property - def photo_album(self) -> 'ImageSet | None': + def photo_album(self) -> ImageSet | None: from onegov.org.models import ImageSetCollection if not self.photo_album_id: return None @@ -1146,12 +1148,12 @@ def photo_album(self) -> 'ImageSet | None': def extend_form( self, - form_class: type['FormT'], - request: 'OrgRequest' - ) -> type['FormT']: + form_class: type[FormT], + request: OrgRequest + ) -> type[FormT]: from onegov.org.models import ImageSetCollection - albums: list['ImageSet'] = ( # noqa: TC201 + albums: list[ImageSet] = ( # noqa: TC201 ImageSetCollection(request.session).query().all() ) if not albums: @@ -1169,14 +1171,14 @@ class PhotoAlbumForm(form_class): # type:ignore name='photo_album_id', ) - def process_obj(self, obj: 'InlinePhotoAlbumExtension') -> None: + def process_obj(self, obj: InlinePhotoAlbumExtension) -> None: super().process_obj(obj) if obj.photo_album_id: self.photo_album_id.data = obj.photo_album_id def populate_obj( self, - obj: 'InlinePhotoAlbumExtension', + obj: InlinePhotoAlbumExtension, *args: Any, **kwargs: Any ) -> None: diff --git a/src/onegov/org/models/external_link.py b/src/onegov/org/models/external_link.py index 8f07274c9c..ed032ecf71 100644 --- a/src/onegov/org/models/external_link.py +++ b/src/onegov/org/models/external_link.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from uuid import uuid4 from onegov.core.collection import GenericCollection @@ -35,24 +37,24 @@ class ExternalLink(Base, ContentMixin, TimestampMixin, AccessExtension, 'lead': {'type': 'localized'}, } - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) - title: 'Column[str]' = Column(Text, nullable=False) - url: 'Column[str]' = Column(Text, nullable=False) + title: Column[str] = Column(Text, nullable=False) + url: Column[str] = Column(Text, nullable=False) page_image: dict_property[str | None] = meta_property() # The collection name this model should appear in - member_of: 'Column[str | None]' = Column(Text, nullable=True) + member_of: Column[str | None] = Column(Text, nullable=True) # TODO: Stop passing title (and maybe even to) as url parameters. # Figure out a way to use the member_of attribute instead. - group: 'Column[str | None]' = Column(Text, nullable=True) + group: Column[str | None] = Column(Text, nullable=True) #: The normalized title for sorting - order: 'Column[str]' = Column(Text, nullable=False, index=True) + order: Column[str] = Column(Text, nullable=False, index=True) es_type_name = 'external_links' es_id = 'title' @@ -73,7 +75,7 @@ class ExternalLinkCollection(GenericCollection[ExternalLink]): def __init__( self, - session: 'Session', + session: Session, member_of: str | None = None, group: str | None = None, type: str | None = None @@ -119,7 +121,7 @@ def target( assert external_link.member_of is not None return cls.collection_by_name()[external_link.member_of] - def query(self) -> 'Query[ExternalLink]': + def query(self) -> Query[ExternalLink]: query = super().query() if self.member_of: query = query.filter_by(member_of=self.member_of) @@ -130,10 +132,10 @@ def query(self) -> 'Query[ExternalLink]': @classmethod def for_model( cls, - session: 'Session', + session: Session, model_class: type[FormCollection | ResourceCollection], **kwargs: Any - ) -> 'Self': + ) -> Self: """ It would be better to use the tablename, but the collections do not always implement the property model_class. """ diff --git a/src/onegov/org/models/file.py b/src/onegov/org/models/file.py index 4c9eb89ec4..9dad13cfb9 100644 --- a/src/onegov/org/models/file.py +++ b/src/onegov/org/models/file.py @@ -1,4 +1,5 @@ """ Contains the models describing files and images. """ +from __future__ import annotations import sedate @@ -15,7 +16,7 @@ from onegov.org.models.extensions import AccessExtension from onegov.org.utils import widest_access from onegov.search import ORMSearchable -from operator import itemgetter +from operator import attrgetter, itemgetter from sedate import standardize_date, utcnow from sqlalchemy import asc, desc, select, nullslast # type: ignore @@ -61,7 +62,7 @@ def query(self) -> Query[FileT]: ... def get_date_intervals( self, today: datetime - ) -> 'Iterator[DateInterval]': + ) -> Iterator[DateInterval]: today = standardize_date(today, 'UTC') month_end = today + relativedelta(day=31) @@ -121,42 +122,42 @@ def get_date_intervals( @overload def query_intervals( self, - intervals: 'Iterable[DateInterval]', - before_filter: 'Callable[[Query[FileT]], Query[_RowT]]', - process: 'Callable[[_RowT], _T]' - ) -> 'Iterator[tuple[str, _T]]': ... + intervals: Iterable[DateInterval], + before_filter: Callable[[Query[FileT]], Query[_RowT]], + process: Callable[[_RowT], _T] + ) -> Iterator[tuple[str, _T]]: ... @overload def query_intervals( self, - intervals: 'Iterable[DateInterval]', + intervals: Iterable[DateInterval], before_filter: None, - process: 'Callable[[FileT], _T]' - ) -> 'Iterator[tuple[str, _T]]': ... + process: Callable[[FileT], _T] + ) -> Iterator[tuple[str, _T]]: ... @overload def query_intervals( self, - intervals: 'Iterable[DateInterval]', + intervals: Iterable[DateInterval], before_filter: None = None, *, - process: 'Callable[[FileT], _T]' - ) -> 'Iterator[tuple[str, _T]]': ... + process: Callable[[FileT], _T] + ) -> Iterator[tuple[str, _T]]: ... @overload def query_intervals( self, - intervals: 'Iterable[DateInterval]', - before_filter: 'Callable[[Query[FileT]], Query[Any]] | None' = None, + intervals: Iterable[DateInterval], + before_filter: Callable[[Query[FileT]], Query[Any]] | None = None, process: None = None - ) -> 'Iterator[tuple[str, Any]]': ... + ) -> Iterator[tuple[str, Any]]: ... def query_intervals( self, - intervals: 'Iterable[DateInterval]', - before_filter: 'Callable[[Query[FileT]], Query[Any]] | None' = None, - process: 'Callable[[Any], Any] | None' = None - ) -> 'Iterator[tuple[str, Any]]': + intervals: Iterable[DateInterval], + before_filter: Callable[[Query[FileT]], Query[Any]] | None = None, + process: Callable[[Any], Any] | None = None + ) -> Iterator[tuple[str, Any]]: base_query = self.query().order_by(desc(File.created)) @@ -176,14 +177,14 @@ def grouped_by_date( self, today: datetime | None = None, id_only: Literal[True] = True - ) -> 'groupby[str, tuple[str, str]]': ... + ) -> groupby[str, tuple[str, str]]: ... @overload def grouped_by_date( self, today: datetime | None, id_only: Literal[False] - ) -> 'groupby[str, tuple[str, FileT]]': ... + ) -> groupby[str, tuple[str, FileT]]: ... @overload def grouped_by_date( @@ -191,13 +192,13 @@ def grouped_by_date( today: datetime | None = None, *, id_only: Literal[False] - ) -> 'groupby[str, tuple[str, FileT]]': ... + ) -> groupby[str, tuple[str, FileT]]: ... def grouped_by_date( self, today: datetime | None = None, id_only: bool = True - ) -> 'groupby[str, tuple[str, FileT | str]]': + ) -> groupby[str, tuple[str, FileT | str]]: """ Returns all files grouped by natural language dates. By default, only ids are returned, as this is enough to build the @@ -211,10 +212,10 @@ def grouped_by_date( files: Iterator[tuple[str, str | FileT]] if id_only: - def before_filter(query: 'Query[FileT]') -> 'Query[IdRow]': + def before_filter(query: Query[FileT]) -> Query[IdRow]: return query.with_entities(File.id) - def process(result: 'IdRow') -> str: + def process(result: IdRow) -> str: return result.id files = self.query_intervals(intervals, before_filter, process) @@ -276,12 +277,42 @@ def es_suggestions(self) -> dict[str, list[str]]: lead: dict_property[str | None] = meta_property() view: dict_property[str | None] = meta_property() + order: dict_property[str] = meta_property(default='by-last-change') + order_direction: dict_property[str] = meta_property(default='desc') + show_images_on_homepage: dict_property[bool | None] = meta_property() + @property + def ordered_files(self) -> list[File]: + if self.order == 'by-last-change': + # the files are already sorted, since this relationship + # is sorted by last change in descending order + if self.order_direction == 'desc': + return self.files + else: + return [*reversed(self.files)] + + sort_key: Callable[[File], str] + if self.order == 'by-name': + sort_key = attrgetter('name') + elif self.order == 'by-caption': + # we can't use attrgetter since note is nullable + def sort_key(file: File) -> str: + return file.note or '' + else: + raise AssertionError('unreachable') + + # for the rest we sort by attribute name + return sorted( + self.files, + key=sort_key, + reverse=self.order_direction == 'desc' + ) + class ImageSetCollection(FileSetCollection[ImageSet]): - def __init__(self, session: 'Session') -> None: + def __init__(self, session: Session) -> None: super().__init__(session, type='image') @@ -307,7 +338,7 @@ class GeneralFileCollection( WHERE type = 'general' """) - def __init__(self, session: 'Session', order_by: str = 'name') -> None: + def __init__(self, session: Session, order_by: str = 'name') -> None: super().__init__(session, type='general', allow_duplicates=False) self.order_by = order_by @@ -315,7 +346,7 @@ def __init__(self, session: 'Session', order_by: str = 'name') -> None: self._last_interval: DateInterval | None = None - def for_order(self, order: str) -> 'Self': + def for_order(self, order: str) -> Self: return self.__class__(self.session, order_by=order) @cached_property @@ -323,7 +354,7 @@ def intervals(self) -> tuple[DateInterval, ...]: return tuple(self.get_date_intervals(today=sedate.utcnow())) @property - def statement(self) -> 'Select': + def statement(self) -> Select: stmt = select(self.file_list.c) if self.order_by == 'name': @@ -340,12 +371,12 @@ def statement(self) -> 'Select': return stmt.order_by(nullslast(direction(order))) @property - def files(self) -> 'Query[FileRow]': + def files(self) -> Query[FileRow]: return self.session.execute(self.statement) - def group(self, record: 'FileRow') -> str: + def group(self, record: FileRow) -> str: - def get_first_character(record: 'FileRow') -> str: + def get_first_character(record: FileRow) -> str: if record.order[0].isdigit(): return '0-9' return record.order[0].upper() @@ -397,5 +428,5 @@ class BaseImageFileCollection( class ImageFileCollection(BaseImageFileCollection[ImageFile]): - def __init__(self, session: 'Session') -> None: + def __init__(self, session: Session) -> None: super().__init__(session, type='image', allow_duplicates=False) diff --git a/src/onegov/org/models/form.py b/src/onegov/org/models/form.py index c0812ee90c..4292ff7ad4 100644 --- a/src/onegov/org/models/form.py +++ b/src/onegov/org/models/form.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form.models import FormDefinition from onegov.org.models.extensions import AccessExtension from onegov.org.models.extensions import ContactExtension @@ -48,10 +50,10 @@ def extensions(self) -> tuple[str, ...]: # type:ignore[override] def submission_deletable( - submission: 'FormSubmission', - session: 'Session', + submission: FormSubmission, + session: Session, payment_blocks: bool = True -) -> 'Ticket | bool': +) -> Ticket | bool: """ CustomFormDefinition's are normally linked to a ticket. Submissions without registration window do not require a decision. The diff --git a/src/onegov/org/models/legacy_file.py b/src/onegov/org/models/legacy_file.py index 235c34bece..3ad3b5d501 100644 --- a/src/onegov/org/models/legacy_file.py +++ b/src/onegov/org/models/legacy_file.py @@ -2,6 +2,7 @@ forward, onegov.file and onegov.org.models.file is used. """ +from __future__ import annotations import base64 @@ -18,13 +19,13 @@ class LegacyFileCollection: - def __init__(self, app: 'OrgApp') -> None: + def __init__(self, app: OrgApp) -> None: assert app.has_filestorage and app.filestorage is not None self.path_prefix = 'files/' self.file_storage = utils.makeopendir(app.filestorage, 'files') - def get_file_by_filename(self, filename: str) -> 'LegacyFile | None': + def get_file_by_filename(self, filename: str) -> LegacyFile | None: if self.file_storage.exists(filename): return LegacyFile(filename) return None @@ -32,13 +33,13 @@ def get_file_by_filename(self, filename: str) -> 'LegacyFile | None': class LegacyImageCollection: - def __init__(self, app: 'OrgApp') -> None: + def __init__(self, app: OrgApp) -> None: assert app.has_filestorage and app.filestorage is not None self.path_prefix = 'images/' self.file_storage = utils.makeopendir(app.filestorage, 'images') - def get_file_by_filename(self, filename: str) -> 'LegacyImage | None': + def get_file_by_filename(self, filename: str) -> LegacyImage | None: if self.file_storage.exists(filename): return LegacyImage(filename) return None @@ -52,7 +53,7 @@ def __init__(self, filename: str, info: dict[str, Any] | None = None): self.info = info or {} @property - def date(self) -> 'date_t | None': + def date(self) -> date_t | None: if 'modified_time' in self.info: return self.info['modified_time'].date() return None @@ -69,7 +70,7 @@ def original_name(self) -> bytes | None: return None @classmethod - def from_url(cls, url: str) -> 'Self': + def from_url(cls, url: str) -> Self: return cls(url.split('/')[-1]) diff --git a/src/onegov/org/models/message.py b/src/onegov/org/models/message.py index 00e66fd581..bb334a4062 100644 --- a/src/onegov/org/models/message.py +++ b/src/onegov/org/models/message.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.chat import Message from onegov.core.elements import Link, Confirm, Intercooler @@ -37,7 +39,7 @@ class TicketMessageMixin: def bound_messages(cls, session: Session) -> MessageCollection[Any]: ... - def link(self, request: 'OrgRequest') -> str: + def link(self, request: OrgRequest) -> str: return request.class_link(Ticket, { 'id': self.meta['id'], 'handler_code': self.meta['handler_code'], @@ -54,11 +56,11 @@ def ticket(self) -> Ticket | None: def create( cls, ticket: Ticket, - request: 'OrgRequest', + request: OrgRequest, text: str | None = None, owner: str | None = None, **extra_meta: Any - ) -> 'Self': + ) -> Self: meta = { 'id': ticket.id.hex, @@ -94,21 +96,21 @@ class TicketNote(Message, TicketMessageMixin): def create( # type:ignore[override] cls, ticket: Ticket, - request: 'OrgRequest', + request: OrgRequest, text: str, - file: 'File | None' = None, + file: File | None = None, owner: str | None = None - ) -> 'Self': + ) -> Self: note = super().create(ticket, request, text=text, owner=owner) note.file = file return note - def formatted_text(self, layout: 'DefaultLayout') -> str: + def formatted_text(self, layout: DefaultLayout) -> str: return hashtag_elements( layout.request, paragraphify(linkify(self.text))) - def links(self, layout: 'DefaultLayout') -> 'Iterator[Link]': + def links(self, layout: DefaultLayout) -> Iterator[Link]: yield Link(_('Edit'), layout.request.link(self, 'edit')) yield Link( _('Delete'), layout.csrf_protected_url(layout.request.link(self)), @@ -151,19 +153,19 @@ class TicketChatMessage(Message, TicketMessageMixin): def create( # type:ignore[override] cls, ticket: Ticket, - request: 'OrgRequest', + request: OrgRequest, text: str, owner: str, origin: str, notify: bool = False, recipient: str | None = None - ) -> 'Self': + ) -> Self: return super().create( ticket, request, text=text, owner=owner, origin=origin, notify=notify, recipient=recipient) - def formatted_text(self, layout: 'DefaultLayout') -> str: + def formatted_text(self, layout: DefaultLayout) -> str: return self.text and hashtag_elements( layout.request, paragraphify(linkify(self.text))) or '' @@ -182,10 +184,10 @@ class TicketMessage(Message, TicketMessageMixin): def create( # type:ignore[override] cls, ticket: Ticket, - request: 'OrgRequest', + request: OrgRequest, change: str, **extra_meta: Any - ) -> 'Self': + ) -> Self: return super().create(ticket, request, change=change, **extra_meta) @@ -198,11 +200,11 @@ class ReservationMessage(Message, TicketMessageMixin): @classmethod def create( # type:ignore[override] cls, - reservations: 'Iterable[Reservation]', + reservations: Iterable[Reservation], ticket: Ticket, - request: 'OrgRequest', + request: OrgRequest, change: str - ) -> 'Self': + ) -> Self: return super().create(ticket, request, change=change, reservations=[ r.id for r in reservations ]) @@ -218,9 +220,9 @@ class SubmissionMessage(Message, TicketMessageMixin): def create( # type:ignore[override] cls, ticket: Ticket, - request: 'OrgRequest', + request: OrgRequest, change: str - ) -> 'Self': + ) -> Self: return super().create(ticket, request, change=change) @@ -235,13 +237,13 @@ def create( # type:ignore[override] cls, event: Event, ticket: Ticket, - request: 'OrgRequest', + request: OrgRequest, change: str - ) -> 'Self': + ) -> Self: return super().create( ticket, request, change=change, event_name=event.name) - def event_link(self, request: 'OrgRequest') -> str: + def event_link(self, request: OrgRequest) -> str: return request.class_link(Event, {'name': self.meta['event_name']}) @@ -254,11 +256,11 @@ class PaymentMessage(Message, TicketMessageMixin): @classmethod def create( # type:ignore[override] cls, - payment: 'Payment', + payment: Payment, ticket: Ticket, - request: 'OrgRequest', + request: OrgRequest, change: str - ) -> 'Self': + ) -> Self: assert payment.amount is not None return super().create( ticket, request, @@ -278,11 +280,11 @@ class DirectoryMessage(Message, TicketMessageMixin): @classmethod def create( # type:ignore[override] cls, - directory: 'Directory', + directory: Directory, ticket: Ticket, - request: 'OrgRequest', + request: OrgRequest, action: str - ) -> 'Self': + ) -> Self: return super().create( ticket, request, directory_id=directory.id.hex, diff --git a/src/onegov/org/models/organisation.py b/src/onegov/org/models/organisation.py index 3fc81c3e8c..7ab0568723 100644 --- a/src/onegov/org/models/organisation.py +++ b/src/onegov/org/models/organisation.py @@ -1,4 +1,5 @@ """ Contains the model describing the organisation proper. """ +from __future__ import annotations from datetime import date, timedelta from functools import cached_property, lru_cache @@ -36,20 +37,20 @@ class Organisation(Base, TimestampMixin): __tablename__ = 'organisations' #: the id of the organisation, an automatically generated uuid - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 ) #: the name of the organisation - name: 'Column[str]' = Column(Text, nullable=False) + name: Column[str] = Column(Text, nullable=False) #: the logo of the organisation - logo_url: 'Column[str | None]' = Column(Text, nullable=True) + logo_url: Column[str | None] = Column(Text, nullable=True) #: the theme options of the organisation - theme_options: 'Column[dict[str, Any] | None]' = Column( + theme_options: Column[dict[str, Any] | None] = Column( JSON, nullable=True, default=user_options.copy @@ -57,7 +58,7 @@ class Organisation(Base, TimestampMixin): #: additional data associated with the organisation # FIXME: This should probably not be nullable - meta: 'Column[dict[str, Any]]' = Column( # type:ignore[assignment] + meta: Column[dict[str, Any]] = Column( # type:ignore[assignment] JSON, nullable=True, default=dict @@ -290,7 +291,7 @@ def has_school_holidays(self) -> bool: return bool(self.holiday_settings.get('school', ())) @property - def school_holidays(self) -> 'Iterator[tuple[date, date]]': + def school_holidays(self) -> Iterator[tuple[date, date]]: """ Returns an iterable that yields date pairs of start and end dates of school holidays """ @@ -304,7 +305,7 @@ def contact(self, value: str | None) -> None: self.__dict__['contact_html'] = paragraphify(linkify(value)) @cached_property - def contact_html(self) -> 'Markup': + def contact_html(self) -> Markup: return paragraphify(linkify(self.contact)) @opening_hours.setter # type:ignore[no-redef] @@ -314,7 +315,7 @@ def opening_hours(self, value: str | None) -> None: self.__dict__['opening_hours_html'] = paragraphify(linkify(value)) @cached_property - def opening_hours_html(self) -> 'Markup': + def opening_hours_html(self) -> Markup: return paragraphify(linkify(self.opening_hours)) @property @@ -330,11 +331,11 @@ def title_lines(self) -> tuple[str, str]: return ' '.join(parts[:-1]), parts[-1] - def excluded_person_fields(self, request: 'OrgRequest') -> list[str]: + def excluded_person_fields(self, request: OrgRequest) -> list[str]: return [] if request.is_logged_in else self.hidden_people_fields @property - def event_filter_fields(self) -> tuple['ParsedField', ...]: + def event_filter_fields(self) -> tuple[ParsedField, ...]: return flatten_event_filter_fields_from_definition( self.event_filter_definition) @@ -342,5 +343,5 @@ def event_filter_fields(self) -> tuple['ParsedField', ...]: @lru_cache(maxsize=64) def flatten_event_filter_fields_from_definition( definition: str -) -> tuple['ParsedField', ...]: +) -> tuple[ParsedField, ...]: return tuple(flatten_fieldsets(parse_formcode(definition))) diff --git a/src/onegov/org/models/page.py b/src/onegov/org/models/page.py index 9efb3de53b..77bd1a38c8 100644 --- a/src/onegov/org/models/page.py +++ b/src/onegov/org/models/page.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import datetime from onegov.core.orm.mixins import ( content_property, dict_markup_property, dict_property, meta_property) @@ -77,7 +79,7 @@ def url_changeable(self) -> bool: return True @property - def paste_target(self) -> 'Topic | News': + def paste_target(self) -> Topic | News: if self.trait == 'link': return self.parent or self # type:ignore[return-value] @@ -106,7 +108,7 @@ def get_form_class( self, trait: str, action: str, - request: 'OrgRequest' + request: OrgRequest ) -> type[LinkForm | PageForm | IframeForm]: if trait == 'link': @@ -182,7 +184,7 @@ def url_changeable(self) -> bool: return self.parent_id is not None @property - def paste_target(self) -> 'Topic | News': + def paste_target(self) -> Topic | News: if self.parent: return self.parent # type:ignore[return-value] else: @@ -199,7 +201,7 @@ def allowed_subtraits(self) -> tuple[str, ...]: def is_supported_trait(self, trait: str) -> bool: return trait in {'news'} - def get_root_page_form_class(self, request: 'OrgRequest') -> type[Form]: + def get_root_page_form_class(self, request: OrgRequest) -> type[Form]: return self.with_content_extensions( Form, request, extensions=( InheritableContactExtension, ContactHiddenOnPageExtension, @@ -211,7 +213,7 @@ def get_form_class( self, trait: str, action: str, - request: 'OrgRequest' + request: OrgRequest ) -> type[Form | PageForm]: if trait == 'news': @@ -240,7 +242,7 @@ def get_form_class( raise NotImplementedError - def for_year(self, year: int) -> 'News': + def for_year(self, year: int) -> News: years_ = set(self.filter_years) years = list(years_ - {year} if year in years_ else years_ | {year}) return News( # type:ignore[misc] @@ -251,7 +253,7 @@ def for_year(self, year: int) -> 'News': filter_tags=sorted(self.filter_tags) ) - def for_tag(self, tag: str) -> 'News': + def for_tag(self, tag: str) -> News: tags_ = set(self.filter_tags) tags = list(tags_ - {tag} if tag in tags_ else tags_ | {tag}) return News( # type:ignore[misc] @@ -265,11 +267,11 @@ def for_tag(self, tag: str) -> 'News': @classmethod def news_query_for( cls, - self: 'News | PageMeta', + self: News | PageMeta, limit: int | None = 2, published_only: bool = True, - session: 'Session | None' = None, - ) -> 'Query[News]': + session: Session | None = None, + ) -> Query[News]: if session is None: session = object_session(self) @@ -322,7 +324,7 @@ def news_query( self, limit: int | None = 2, published_only: bool = True - ) -> 'Query[News]': + ) -> Query[News]: return self.news_query_for(self, limit, published_only) diff --git a/src/onegov/org/models/page_move.py b/src/onegov/org/models/page_move.py index 04ee9159e5..cee719684c 100644 --- a/src/onegov/org/models/page_move.py +++ b/src/onegov/org/models/page_move.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.page import Page, PageCollection @@ -14,14 +16,14 @@ class AdjacencyListMove(Generic[_L]): """ Represents a single move of an adjacency list item. """ - __collection__: type['AdjacencyListCollection[_L]'] + __collection__: type[AdjacencyListCollection[_L]] def __init__( self, - session: 'Session', + session: Session, subject: _L, target: _L, - direction: 'MoveDirection' + direction: MoveDirection ) -> None: self.session = session self.subject = subject diff --git a/src/onegov/org/models/person_move.py b/src/onegov/org/models/person_move.py index fed0f96024..f7d95a516e 100644 --- a/src/onegov/org/models/person_move.py +++ b/src/onegov/org/models/person_move.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.page import Page from onegov.form import FormDefinition from onegov.reservation import Resource @@ -23,11 +25,11 @@ class PersonMove(Generic[_OwnerT]): def __init__( self, - session: 'Session', + session: Session, obj: _OwnerT, subject: str, target: str, - direction: 'MoveDirection' + direction: MoveDirection ) -> None: self.session = session @@ -48,7 +50,7 @@ def execute(self) -> None: @staticmethod def get_implementation( obj: object - ) -> type['PagePersonMove | FormPersonMove | ResourcePersonMove']: + ) -> type[PagePersonMove | FormPersonMove | ResourcePersonMove]: # XXX this is not really extendable by other org applications. They # need to override this function *and* define new paths for each class # they add. @@ -115,5 +117,5 @@ class ResourcePersonMove(PersonMove[ """ Represents a single move of a linked person on a form definition. """ @property - def key(self) -> 'UUID': + def key(self) -> UUID: return self.obj.id diff --git a/src/onegov/org/models/publication.py b/src/onegov/org/models/publication.py index 080400f244..af3261223e 100644 --- a/src/onegov/org/models/publication.py +++ b/src/onegov/org/models/publication.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate from datetime import datetime @@ -15,7 +17,7 @@ class PublicationCollection(GenericCollection[File]): - def __init__(self, session: 'Session', year: int | None = None) -> None: + def __init__(self, session: Session, year: int | None = None) -> None: super().__init__(session) self.year = year @@ -23,7 +25,7 @@ def __init__(self, session: 'Session', year: int | None = None) -> None: def model_class(self) -> type[File]: return File - def query(self) -> 'Query[File]': + def query(self) -> Query[File]: query = super().query().filter( self.model_class.published.is_(True), self.model_class.publication.is_(True), @@ -40,10 +42,10 @@ def query(self) -> 'Query[File]': return query - def for_year(self, year: int | None) -> 'Self': + def for_year(self, year: int | None) -> Self: return self.__class__(self.session, year) - def first_year(self, timezone: 'TzInfoOrName') -> int | None: + def first_year(self, timezone: TzInfoOrName) -> int | None: query = ( self.for_year(None).query() .with_entities(File.created) diff --git a/src/onegov/org/models/recipient.py b/src/onegov/org/models/recipient.py index df03195585..c2eba2d7fb 100644 --- a/src/onegov/org/models/recipient.py +++ b/src/onegov/org/models/recipient.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm.mixins import content_property, dict_property from onegov.recipient import GenericRecipient, GenericRecipientCollection @@ -21,5 +23,5 @@ class ResourceRecipient(GenericRecipient): class ResourceRecipientCollection( GenericRecipientCollection[ResourceRecipient] ): - def __init__(self, session: 'Session') -> None: + def __init__(self, session: Session) -> None: super().__init__(session, type='resource') diff --git a/src/onegov/org/models/resource.py b/src/onegov/org/models/resource.py index 8bbc7b986e..f02a7fad99 100644 --- a/src/onegov/org/models/resource.py +++ b/src/onegov/org/models/resource.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sedate from datetime import date, datetime @@ -34,7 +36,7 @@ class FindYourSpotCollection(ResourceCollection): - def __init__(self, libres_context: 'Context', group: str | None) -> None: + def __init__(self, libres_context: Context, group: str | None) -> None: super().__init__(libres_context) self.group = group @@ -46,7 +48,7 @@ def title(self) -> str: def meta(self) -> dict[str, Any]: return {'lead': _('Search for available dates')} - def query(self) -> 'Query[Resource]': + def query(self) -> Query[Resource]: query = self.session.query(Resource) # we only support find-your-spot for rooms for now query = query.filter(Resource.type == 'room') @@ -85,12 +87,12 @@ def deletable(self) -> bool: return True @property - def future_managed_reservations(self) -> 'Query[Reservation]': + def future_managed_reservations(self) -> Query[Reservation]: return self.scheduler.managed_reservations().filter( # type:ignore Reservation.end >= sedate.utcnow()) @property - def future_managed_reserved_slots(self) -> 'Query[ReservedSlot]': + def future_managed_reserved_slots(self) -> Query[ReservedSlot]: return self.scheduler.managed_reserved_slots().filter( ReservedSlot.end >= sedate.utcnow()) @@ -138,9 +140,9 @@ def remove_expired_reservation_sessions( def bound_reservations( self, - request: 'OrgRequest', + request: OrgRequest, status: str = 'pending' - ) -> 'Query[Reservation]': + ) -> Query[Reservation]: """ The reservations associated with this resource and user. """ session = self.bound_session_id(request) @@ -157,7 +159,7 @@ def bound_reservations( return res # type:ignore[return-value] - def bound_session_id(self, request: 'OrgRequest') -> 'uuid.UUID': + def bound_session_id(self, request: OrgRequest) -> uuid.UUID: """ The session id associated with this resource and user. """ if not request.browser_session.has('libres_session_id'): request.browser_session.libres_session_id = uuid4() @@ -169,7 +171,7 @@ def reservations_with_tickets_query( start: datetime | None = None, end: datetime | None = None, exclude_pending: bool = True - ) -> 'Query[Reservation]': + ) -> Query[Reservation]: """ Returns a query which joins this resource's reservations between start and end with the tickets table. diff --git a/src/onegov/org/models/search.py b/src/onegov/org/models/search.py index 3177130e67..c92b48795f 100644 --- a/src/onegov/org/models/search.py +++ b/src/onegov/org/models/search.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from elasticsearch_dsl.function import SF # type:ignore from elasticsearch_dsl.query import FunctionScore # type:ignore from elasticsearch_dsl.query import Match @@ -19,7 +21,7 @@ class Search(Pagination[_M]): results_per_page = 10 max_query_length = 100 - def __init__(self, request: 'OrgRequest', query: str, page: int) -> None: + def __init__(self, request: OrgRequest, query: str, page: int) -> None: super().__init__(page) self.request = request self.query = query @@ -46,20 +48,20 @@ def __eq__(self, other: object) -> bool: if TYPE_CHECKING: @property - def cached_subset(self) -> 'Response | None': ... # type:ignore + def cached_subset(self) -> Response | None: ... # type:ignore - def subset(self) -> 'Response | None': # type:ignore[override] + def subset(self) -> Response | None: # type:ignore[override] return self.batch @property def page_index(self) -> int: return self.page - def page_by_index(self, index: int) -> 'Search[_M]': + def page_by_index(self, index: int) -> Search[_M]: return Search(self.request, self.query, index) @cached_property - def batch(self) -> 'Response | None': # type:ignore[override] + def batch(self) -> Response | None: # type:ignore[override] if not self.query: return None @@ -80,7 +82,7 @@ def batch(self) -> 'Response | None': # type:ignore[override] return search[self.offset:self.offset + self.batch_size].execute() @cached_property - def load_batch_results(self) -> list['Hit']: + def load_batch_results(self) -> list[Hit]: """Load search results and sort events by latest occurrence. This methods is a wrapper around `batch.load()`, which returns the @@ -110,9 +112,9 @@ def get_sort_key(event: Event) -> float: def generic_search( self, - search: 'ESSearch', + search: ESSearch, query: str - ) -> 'ESSearch': + ) -> ESSearch: # make sure the title matches with a higher priority, otherwise the # "get lucky" functionality is not so lucky after all @@ -139,7 +141,7 @@ def generic_search( return search - def hashtag_search(self, search: 'ESSearch', query: str) -> 'ESSearch': + def hashtag_search(self, search: ESSearch, query: str) -> ESSearch: return search.query(Match(es_tags=query.lstrip('#'))) def feeling_lucky(self) -> str | None: diff --git a/src/onegov/org/models/sitecollection.py b/src/onegov/org/models/sitecollection.py index 6bb9355462..f4d6a0e96d 100644 --- a/src/onegov/org/models/sitecollection.py +++ b/src/onegov/org/models/sitecollection.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.form.models import FormDefinition from onegov.reservation import Resource from onegov.directory import Directory @@ -13,11 +15,11 @@ class SiteCollection: - def __init__(self, session: 'Session') -> None: + def __init__(self, session: Session) -> None: self.session = session @staticmethod - def get_topics(session: 'Session') -> 'Query[Topic]': + def get_topics(session: Session) -> Query[Topic]: topics = session.query(Topic) topics = topics.options(defer(Topic.meta)) topics = topics.options(defer(Topic.content)) @@ -26,7 +28,7 @@ def get_topics(session: 'Session') -> 'Query[Topic]': return topics @staticmethod - def get_news(session: 'Session') -> 'Query[News]': + def get_news(session: Session) -> Query[News]: news = session.query(News) news = news.options(defer(News.meta)) news = news.options(defer(News.content)) @@ -35,7 +37,7 @@ def get_news(session: 'Session') -> 'Query[News]': return news @staticmethod - def get_forms(session: 'Session') -> 'Query[FormDefinition]': + def get_forms(session: Session) -> Query[FormDefinition]: forms = session.query(FormDefinition) forms = forms.options(defer(FormDefinition.definition)) forms = forms.options(defer(FormDefinition.checksum)) @@ -43,14 +45,14 @@ def get_forms(session: 'Session') -> 'Query[FormDefinition]': return forms @staticmethod - def get_resources(session: 'Session') -> 'Query[Resource]': + def get_resources(session: Session) -> Query[Resource]: resources = session.query(Resource) resources = resources.options(defer(Resource.timezone)) resources = resources.order_by(Resource.title) return resources @staticmethod - def get_directories(session: 'Session') -> 'Query[Directory]': + def get_directories(session: Session) -> Query[Directory]: directories = session.query(Directory) directories = directories.options(defer(Directory.meta)) directories = directories.options(defer(Directory.content)) @@ -61,7 +63,7 @@ def get_directories(session: 'Session') -> 'Query[Directory]': return directories @staticmethod - def get_imagesets(session: 'Session') -> 'Query[ImageSet]': + def get_imagesets(session: Session) -> Query[ImageSet]: imagesets = session.query(ImageSet) imagesets = imagesets.options(defer(ImageSet.meta)) imagesets = imagesets.options(defer(ImageSet.content)) diff --git a/src/onegov/org/models/swiss_holidays.py b/src/onegov/org/models/swiss_holidays.py index 3bf6e1db91..a56fc59022 100644 --- a/src/onegov/org/models/swiss_holidays.py +++ b/src/onegov/org/models/swiss_holidays.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from collections import defaultdict from datetime import date, datetime from dateutil.easter import easter @@ -65,8 +67,8 @@ class SwissHolidays: def __init__( self, - cantons: 'Iterable[str]' = (), - other: 'Iterable[tuple[int, int, str]]' = (), + cantons: Iterable[str] = (), + other: Iterable[tuple[int, int, str]] = (), timezone: str = 'Europe/Zurich' ) -> None: @@ -150,7 +152,7 @@ def between( # tested this more than two years? years = (start.year, end.year) - def generate() -> 'Iterator[tuple[date, list[str]]]': + def generate() -> Iterator[tuple[date, list[str]]]: for year in years: for dt, descriptions in self.all(year): if start <= dt and dt <= end: @@ -158,13 +160,13 @@ def generate() -> 'Iterator[tuple[date, list[str]]]': return list(generate()) - def other(self, year: int) -> 'Iterator[tuple[date, set[str]]]': + def other(self, year: int) -> Iterator[tuple[date, set[str]]]: """ Returns all custom defined holidays for the given year. """ for month, day in self._other: yield date(year, month, day), self._other[(month, day)] - def official(self, year: int) -> 'Iterator[tuple[date, tuple[str, ...]]]': + def official(self, year: int) -> Iterator[tuple[date, tuple[str, ...]]]: """ Like :meth:`all`, but only includes the official holidays, not the custom defined ones. diff --git a/src/onegov/org/models/tan.py b/src/onegov/org/models/tan.py index f4f44bf472..91a0c6e65d 100644 --- a/src/onegov/org/models/tan.py +++ b/src/onegov/org/models/tan.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from datetime import timedelta from uuid import uuid4 @@ -32,21 +34,21 @@ class TANAccess(Base, TimestampMixin): Index('ix_tan_accesses_created', 'created'), ) - id: 'Column[uuid.UUID]' = Column( + id: Column[uuid.UUID] = Column( UUID, # type: ignore[arg-type] primary_key=True, default=uuid4 ) # for an mTAN session this would be the phone number - session_id: 'Column[str]' = Column( + session_id: Column[str] = Column( Text, index=True, nullable=False ) # The url that was accessed - url: 'Column[str]' = Column( + url: Column[str] = Column( Text, index=True, nullable=False @@ -57,7 +59,7 @@ class TANAccessCollection(GenericCollection[TANAccess]): def __init__( self, - session: 'Session', + session: Session, session_id: str, access_window: timedelta = DEFAULT_ACCESS_WINDOW, ): @@ -69,7 +71,7 @@ def __init__( def model_class(self) -> type[TANAccess]: return TANAccess - def query(self) -> 'Query[TANAccess]': + def query(self) -> Query[TANAccess]: cutoff = TANAccess.timestamp() - self.access_window return self.session.query(TANAccess).filter( TANAccess.session_id == self.session_id diff --git a/src/onegov/org/models/ticket.py b/src/onegov/org/models/ticket.py index f25e885e49..815dad4a8b 100644 --- a/src/onegov/org/models/ticket.py +++ b/src/onegov/org/models/ticket.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from markupsafe import Markup from onegov.chat.collections import ChatCollection @@ -52,7 +54,7 @@ class OrgTicketMixin: number: Column[str] group: Column[str] - def reference(self, request: 'OrgRequest') -> str: + def reference(self, request: OrgRequest) -> str: """ Returns the reference which should be used wherever we talk about a ticket, but do not show it (say in an e-mail subject). @@ -64,7 +66,7 @@ def reference(self, request: 'OrgRequest') -> str: """ return f'{self.number} / {self.reference_group(request)}' - def reference_group(self, request: 'OrgRequest') -> str: + def reference_group(self, request: OrgRequest) -> str: return request.translate(self.group) @cached_property @@ -116,12 +118,12 @@ class EventSubmissionTicket(OrgTicketMixin, Ticket): es_type_name = 'event_tickets' if TYPE_CHECKING: - handler: 'EventSubmissionHandler' + handler: EventSubmissionHandler - def reference_group(self, request: 'OrgRequest') -> str: + def reference_group(self, request: OrgRequest) -> str: return self.title - def unguessable_edit_link(self, request: 'OrgRequest') -> str | None: + def unguessable_edit_link(self, request: OrgRequest) -> str | None: if ( self.handler and self.handler.ticket @@ -147,7 +149,7 @@ class DirectoryEntryTicket(OrgTicketMixin, Ticket): @handlers.registered_handler('FRM') class FormSubmissionHandler(Handler): - id: 'UUID' + id: UUID handler_title = _('Form Submissions') code_title = _('Forms') @@ -157,11 +159,11 @@ def collection(self) -> FormSubmissionCollection: return FormSubmissionCollection(self.session) @cached_property - def submission(self) -> 'FormSubmission | None': + def submission(self) -> FormSubmission | None: return self.collection.by_id(self.id) @cached_property - def form(self) -> 'Form': + def form(self) -> Form: assert self.submission is not None return self.submission.form_class(data=self.submission.data) @@ -197,7 +199,7 @@ def group(self) -> str: ) @property - def payment(self) -> 'Payment | None': + def payment(self) -> Payment | None: return self.submission.payment if self.submission is not None else None @property @@ -225,7 +227,7 @@ def undecided(self) -> bool: def get_summary( self, - request: 'OrgRequest' # type:ignore[override] + request: OrgRequest # type:ignore[override] ) -> Markup: layout = DefaultLayout(self.submission, request) @@ -238,7 +240,7 @@ def get_summary( def get_links( # type:ignore[override] self, - request: 'OrgRequest' # type:ignore[override] + request: OrgRequest # type:ignore[override] ) -> list[Link | LinkGroup]: layout = DefaultLayout(self.submission, request) @@ -366,7 +368,7 @@ def get_links( # type:ignore[override] @handlers.registered_handler('RSV') class ReservationHandler(Handler): - id: 'UUID' + id: UUID handler_title = _('Reservations') code_title = _('Reservations') @@ -380,7 +382,7 @@ def resource(self) -> Resource | None: return query.one() - def reservations_query(self) -> 'Query[Reservation]': + def reservations_query(self) -> Query[Reservation]: # libres allows for multiple reservations with a single request (token) # for now we don't really have that case in onegov.org, but we # try to be aware of it as much as possible @@ -410,11 +412,11 @@ def most_future_reservation(self) -> Reservation | None: ) @cached_property - def submission(self) -> 'FormSubmission | None': + def submission(self) -> FormSubmission | None: return FormSubmissionCollection(self.session).by_id(self.id) @property - def payment(self) -> 'Payment | None': + def payment(self) -> Payment | None: return self.reservations and self.reservations[0].payment or None @property @@ -490,10 +492,10 @@ def group(self) -> str | None: @classmethod def handle_extra_parameters( cls, - session: 'Session', - query: '_Q', + session: Session, + query: _Q, extra_parameters: dict[str, Any] - ) -> '_Q': + ) -> _Q: if 'allocation_id' in extra_parameters: allocations = session.query(Allocation.group) @@ -515,7 +517,7 @@ def handle_extra_parameters( def get_summary( self, - request: 'OrgRequest' # type:ignore[override] + request: OrgRequest # type:ignore[override] ) -> Markup: layout = DefaultLayout(self.resource, request) @@ -542,7 +544,7 @@ def get_summary( def get_links( # type:ignore[override] self, - request: 'OrgRequest' # type:ignore[override] + request: OrgRequest # type:ignore[override] ) -> list[Link | LinkGroup]: if self.deleted: @@ -662,7 +664,7 @@ def get_links( # type:ignore[override] @handlers.registered_handler('EVN') class EventSubmissionHandler(Handler): - id: 'UUID' + id: UUID handler_title = _('Events') code_title = _('Events') @@ -671,7 +673,7 @@ def collection(self) -> EventCollection: return EventCollection(self.session) @cached_property - def event(self) -> 'Event | None': + def event(self) -> Event | None: return self.collection.by_id(self.id) @property @@ -734,7 +736,7 @@ def group(self) -> str: def get_summary( self, - request: 'OrgRequest' # type:ignore[override] + request: OrgRequest # type:ignore[override] ) -> Markup: assert self.event is not None layout = EventLayout(self.event, request) @@ -747,7 +749,7 @@ def get_summary( def get_links( # type:ignore[override] self, - request: 'OrgRequest' # type:ignore[override] + request: OrgRequest # type:ignore[override] ) -> list[Link | LinkGroup]: links: list[Link | LinkGroup] = [] @@ -834,7 +836,7 @@ def get_links( # type:ignore[override] @handlers.registered_handler('DIR') class DirectoryEntryHandler(Handler): - id: 'UUID' + id: UUID handler_title = _('Directory Entry Submissions') code_title = _('Directory Entry Submissions') @@ -844,11 +846,11 @@ def collection(self) -> FormSubmissionCollection: return FormSubmissionCollection(self.session) @cached_property - def submission(self) -> 'FormSubmission | None': + def submission(self) -> FormSubmission | None: return self.collection.by_id(self.id) @cached_property - def form(self) -> 'Form | None': + def form(self) -> Form | None: return ( self.submission.form_class(data=self.submission.data) if self.submission is not None else None @@ -960,7 +962,7 @@ def group(self) -> str: return '-' @property - def payment(self) -> 'Payment | None': + def payment(self) -> Payment | None: return self.submission.payment if self.submission else None @property @@ -995,7 +997,7 @@ def kind(self) -> str: def get_summary( self, - request: 'OrgRequest' # type:ignore[override] + request: OrgRequest # type:ignore[override] ) -> Markup: assert self.form is not None @@ -1015,7 +1017,7 @@ def get_summary( def get_links( # type:ignore[override] self, - request: 'OrgRequest' # type:ignore[override] + request: OrgRequest # type:ignore[override] ) -> list[Link | LinkGroup]: links: list[Link | LinkGroup] = [] @@ -1156,7 +1158,7 @@ class ChatTicket(OrgTicketMixin, Ticket): __mapper_args__ = {'polymorphic_identity': 'CHT'} # type:ignore es_type_name = 'chat_tickets' - def reference_group(self, request: 'OrgRequest') -> str: + def reference_group(self, request: OrgRequest) -> str: return self.handler.title @@ -1171,7 +1173,7 @@ def collection(self) -> ChatCollection: return ChatCollection(self.session) @cached_property - def chat(self) -> 'Chat | None': + def chat(self) -> Chat | None: return self.collection.by_id(self.id) @property @@ -1199,7 +1201,7 @@ def email(self) -> str: def get_summary( self, - request: 'OrgRequest' # type: ignore[override] + request: OrgRequest # type: ignore[override] ) -> Markup: layout = DefaultLayout(self.collection, request) @@ -1212,6 +1214,6 @@ def get_summary( def get_links( # type: ignore[override] self, - request: 'OrgRequest' # type: ignore[override] + request: OrgRequest # type: ignore[override] ) -> list[Link | LinkGroup]: return [] diff --git a/src/onegov/org/models/traitinfo.py b/src/onegov/org/models/traitinfo.py index 076fd4956f..466b0375c2 100644 --- a/src/onegov/org/models/traitinfo.py +++ b/src/onegov/org/models/traitinfo.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.org import _ from onegov.org.elements import DeleteLink, Link, LinkGroup, IFrameLink from onegov.org.models import Organisation @@ -101,12 +103,12 @@ def trait_messages(self) -> dict[str, dict[str, str]]: return TRAIT_MESSAGES @property - def allowed_subtraits(self) -> 'Sequence[str]': + def allowed_subtraits(self) -> Sequence[str]: """ Returns a list of traits that this page may contain. """ raise NotImplementedError @property - def paste_target(self) -> 'TraitInfo': + def paste_target(self) -> TraitInfo: """ Returns the page that should be used as parent for the content pasting if paste is called on the current page (self). @@ -129,15 +131,15 @@ def get_form_class( self, trait: str, action: str, - request: 'OrgRequest' - ) -> type['Form']: + request: OrgRequest + ) -> type[Form]: """ Returns the form class for the given trait, action. """ raise NotImplementedError def get_editbar_links( self, - request: 'OrgRequest' - ) -> 'Sequence[BaseLink | LinkGroup]': + request: OrgRequest + ) -> Sequence[BaseLink | LinkGroup]: """ Returns the editbar links on the private view of this trait. """ links = list(self.get_edit_links(request)) links.append( @@ -151,8 +153,8 @@ def get_editbar_links( def get_add_links( self, - request: 'OrgRequest' - ) -> 'Iterator[BaseLink]': + request: OrgRequest + ) -> Iterator[BaseLink]: """ Yields the add links shown on the private view of this trait. """ for trait in self.allowed_subtraits: @@ -170,8 +172,8 @@ def get_add_links( def get_edit_links( self, - request: 'OrgRequest' - ) -> 'Iterator[BaseLink | LinkGroup]': + request: OrgRequest + ) -> Iterator[BaseLink | LinkGroup]: """ Yields the edit links shown on the private view of this trait. """ if self.editable: diff --git a/src/onegov/org/observer.py b/src/onegov/org/observer.py index 84c03f9af3..630140cfa6 100644 --- a/src/onegov/org/observer.py +++ b/src/onegov/org/observer.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.core.orm import observes as base_observes @@ -8,5 +10,5 @@ _F = TypeVar('_F', bound=Callable[..., Any]) -def observes(*paths: str) -> 'Callable[[_F], _F]': +def observes(*paths: str) -> Callable[[_F], _F]: return base_observes(*paths, scope='onegov.org.app.OrgApp') diff --git a/src/onegov/org/open_graph.py b/src/onegov/org/open_graph.py index d0a34ba4c9..002824935d 100644 --- a/src/onegov/org/open_graph.py +++ b/src/onegov/org/open_graph.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.file import File @@ -99,7 +101,7 @@ def og_locale(self) -> str | None: return self.request.locale @property - def og_locale_alternate(self) -> 'Iterator[str]': + def og_locale_alternate(self) -> Iterator[str]: return ( locale for locale in self.request.app.settings.i18n.locales diff --git a/src/onegov/org/path.py b/src/onegov/org/path.py index 8733ddcc0f..249c018ca1 100644 --- a/src/onegov/org/path.py +++ b/src/onegov/org/path.py @@ -1,4 +1,6 @@ """ Contains the paths to the different models served by onegov.org. """ +from __future__ import annotations + from onegov.form.models.definition import SurveyDefinition import sedate @@ -207,7 +209,7 @@ def get_news( @OrgApp.path(model=GeneralFileCollection, path='/files') def get_files( - request: 'OrgRequest', + request: OrgRequest, order_by: str = 'name' ) -> GeneralFileCollection: return GeneralFileCollection(request.session, order_by=order_by) @@ -219,12 +221,12 @@ def get_images(app: OrgApp) -> ImageFileCollection: @OrgApp.path(model=ExportCollection, path='/exports') -def get_exports(request: 'OrgRequest', app: OrgApp) -> ExportCollection: +def get_exports(request: OrgRequest, app: OrgApp) -> ExportCollection: return ExportCollection(app) @OrgApp.path(model=Export, path='/export/{id}') -def get_export(request: 'OrgRequest', app: OrgApp, id: str) -> Export | None: +def get_export(request: OrgRequest, app: OrgApp, id: str) -> Export | None: return ExportCollection(app).by_id(id) @@ -283,7 +285,7 @@ def get_complete_form_submission( path='/form-registration-window/{id}', converters={'id': UUID}) def get_form_registration_window( - request: 'OrgRequest', + request: OrgRequest, id: UUID ) -> FormRegistrationWindow | None: return FormCollection(request.session).registration_windows.by_id(id) @@ -294,7 +296,7 @@ def get_form_registration_window( path='/survey-submission-window/{id}', converters={'id': UUID}) def get_survey_submission_window( - request: 'OrgRequest', + request: OrgRequest, id: UUID ) -> SurveySubmissionWindow | None: return SurveyCollection(request.session).submission_windows.by_id(id) @@ -302,7 +304,7 @@ def get_survey_submission_window( @OrgApp.path(model=File, path='/storage/{id}') def get_file_for_org( - request: 'OrgRequest', + request: OrgRequest, app: OrgApp, id: str ) -> File | None: @@ -424,7 +426,7 @@ def get_ticket(app: OrgApp, handler_code: str, id: UUID) -> Ticket | None: def get_tickets( app: OrgApp, handler: str = 'ALL', - state: 'ExtendedTicketState' = 'open', + state: ExtendedTicketState = 'open', page: int = 0, group: str | None = None, owner: str | None = None, @@ -546,7 +548,7 @@ def get_reservation( @OrgApp.path(model=Clipboard, path='/clipboard/copy/{token}') -def get_clipboard(request: 'OrgRequest', token: str) -> Clipboard | None: +def get_clipboard(request: OrgRequest, token: str) -> Clipboard | None: clipboard = Clipboard(request, token) # the url is None if the token is invalid @@ -689,7 +691,7 @@ def get_resource_move( ) def get_occurrences( app: OrgApp, - request: 'OrgRequest', + request: OrgRequest, page: int = 0, range: DateRange | None = None, start: date | None = None, @@ -736,7 +738,7 @@ def get_event(app: OrgApp, name: str) -> Event | None: @OrgApp.path(model=Search, path='/search', converters={'page': int}) def get_search( - request: 'OrgRequest', + request: OrgRequest, q: str = '', page: int = 0 ) -> Search[Any]: @@ -744,7 +746,7 @@ def get_search( @OrgApp.path(model=AtoZPages, path='/a-z') -def get_a_to_z(request: 'OrgRequest') -> AtoZPages: +def get_a_to_z(request: OrgRequest) -> AtoZPages: return AtoZPages(request) @@ -935,7 +937,7 @@ def get_directory(app: OrgApp, name: str) -> Directory | None: 'upcoming_only': bool }) def get_directory_entries( - request: 'OrgRequest', + request: OrgRequest, app: OrgApp, directory_name: str, keywords: dict[str, list[str]], @@ -1025,7 +1027,7 @@ def get_directory_submission_action( path='/publications', converters={'year': int}) def get_publication_collection( - request: 'OrgRequest', + request: OrgRequest, year: int | None = None ) -> PublicationCollection: year = year or sedate.to_timezone(sedate.utcnow(), 'Europe/Zurich').year @@ -1035,7 +1037,7 @@ def get_publication_collection( @OrgApp.path( model=Dashboard, path='/dashboard') -def get_dashboard(request: 'OrgRequest') -> Dashboard | None: +def get_dashboard(request: OrgRequest) -> Dashboard | None: dashboard = Dashboard(request) if dashboard.is_available: @@ -1045,7 +1047,7 @@ def get_dashboard(request: 'OrgRequest') -> Dashboard | None: @OrgApp.path(model=ExternalLinkCollection, path='/external-links') def get_external_link_collection( - request: 'OrgRequest', + request: OrgRequest, type: str | None = None ) -> ExternalLinkCollection: return ExternalLinkCollection(request.session, type=type) @@ -1053,7 +1055,7 @@ def get_external_link_collection( @OrgApp.path(model=ExternalLink, path='/external-link/{id}', converters={'id': UUID}) -def get_external_link(request: 'OrgRequest', id: UUID) -> ExternalLink | None: +def get_external_link(request: OrgRequest, id: UUID) -> ExternalLink | None: return ExternalLinkCollection(request.session).by_id(id) @@ -1088,5 +1090,5 @@ def get_qr_code( @OrgApp.path( model=ApiKey, path='/api_keys/{key}/delete', converters={'key': UUID} ) -def get_api_key_for_delete(request: 'OrgRequest', key: UUID) -> ApiKey | None: +def get_api_key_for_delete(request: OrgRequest, key: UUID) -> ApiKey | None: return request.session.query(ApiKey).filter_by(key=key).first() diff --git a/src/onegov/org/pdf/ticket.py b/src/onegov/org/pdf/ticket.py index 7cf0d215db..ee9ae453ff 100644 --- a/src/onegov/org/pdf/ticket.py +++ b/src/onegov/org/pdf/ticket.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.org import _ from datetime import date from functools import partial @@ -89,8 +91,8 @@ def h3(self, title: str) -> None: # type:ignore[override] @staticmethod def page_fn_header_and_footer( - canvas: 'Canvas', - doc: 'Template' + canvas: Canvas, + doc: Template ) -> None: page_fn_header(canvas, doc) @@ -106,14 +108,14 @@ def page_fn_header_and_footer( canvas.drawRightString( doc.pagesize[0] - doc.rightMargin, doc.bottomMargin / 2, - f'{canvas.getPageNumber()}' + f'{canvas.getPageNumber()}' # type:ignore[no-untyped-call] ) canvas.restoreState() @staticmethod def page_fn_header_and_footer_qr( - canvas: 'Canvas', - doc: 'Template' + canvas: Canvas, + doc: Template ) -> None: assert hasattr(doc, 'qr_payload') @@ -133,20 +135,20 @@ def page_fn_header_and_footer_qr( canvas.restoreState() @property - def page_fn(self) -> 'Callable[[Canvas, Template], None]': + def page_fn(self) -> Callable[[Canvas, Template], None]: """ First page the same as later except Qr-Code ...""" return self.page_fn_header_and_footer_qr @property - def page_fn_later(self) -> 'Callable[[Canvas, Template], None]': + def page_fn_later(self) -> Callable[[Canvas, Template], None]: return self.page_fn_header_and_footer @overload # type:ignore[override] def table( self, - data: 'Sequence[Sequence[str | Paragraph]]', - columns: 'Literal["even"] | Sequence[float | None] | None', - style: 'TableStyle | Iterable[_TableCommand] | None' = None, + data: Sequence[Sequence[str | Paragraph]], + columns: Literal['even'] | Sequence[float | None] | None, + style: TableStyle | Iterable[_TableCommand] | None = None, ratios: Literal[False] = False, border: bool = True, first_bold: bool = True @@ -155,9 +157,9 @@ def table( @overload def table( self, - data: 'Sequence[Sequence[str | Paragraph]]', + data: Sequence[Sequence[str | Paragraph]], columns: Literal['even'] | list[float] | None, - style: 'TableStyle | Iterable[_TableCommand] | None' = None, + style: TableStyle | Iterable[_TableCommand] | None = None, *, ratios: Literal[True], border: bool = True, @@ -167,9 +169,9 @@ def table( @overload def table( self, - data: 'Sequence[Sequence[str | Paragraph]]', + data: Sequence[Sequence[str | Paragraph]], columns: Literal['even'] | list[float] | None, - style: 'TableStyle | Iterable[_TableCommand] | None', + style: TableStyle | Iterable[_TableCommand] | None, ratios: Literal[True], border: bool = True, first_bold: bool = True @@ -178,9 +180,9 @@ def table( @overload def table( self, - data: 'Sequence[Sequence[str | Paragraph]]', - columns: 'Literal["even"] | Sequence[float | None] | None', - style: 'TableStyle | Iterable[_TableCommand] | None' = None, + data: Sequence[Sequence[str | Paragraph]], + columns: Literal['even'] | Sequence[float | None] | None, + style: TableStyle | Iterable[_TableCommand] | None = None, ratios: bool = False, border: bool = True, first_bold: bool = True @@ -188,9 +190,9 @@ def table( def table( self, - data: 'Sequence[Sequence[str | Paragraph]]', - columns: 'Literal["even"] | Sequence[float | None] | None', - style: 'TableStyle | Iterable[_TableCommand] | None' = None, + data: Sequence[Sequence[str | Paragraph]], + columns: Literal['even'] | Sequence[float | None] | None, + style: TableStyle | Iterable[_TableCommand] | None = None, ratios: bool = False, border: bool = True, first_bold: bool = True @@ -238,9 +240,9 @@ def ticket_summary(self, html: str | None, linkify: bool = True) -> None: underline_width = self.underline_width def colorize( - attrs: '_HTMLAttrs', + attrs: _HTMLAttrs, new: bool = False - ) -> '_HTMLAttrs': + ) -> _HTMLAttrs: # phone numbers appear here but are escaped, skip... if not attrs.get((None, 'href')): @@ -369,12 +371,12 @@ def ticket_payment(self) -> None: def p_markup( self, text: str, - style: 'PropertySet | None' = None + style: PropertySet | None = None ) -> None: super().p_markup(self.translate(text), style) - def ticket_timeline(self, msg_feed: 'Mapping[str, Any] | None') -> None: + def ticket_timeline(self, msg_feed: Mapping[str, Any] | None) -> None: """Will parse the timeline from view_messages_feed """ if not msg_feed or not msg_feed['messages']: return @@ -437,8 +439,8 @@ def extract_feed_info(html: str) -> list[str | None] | None: @classmethod def from_ticket( cls, - request: 'OrgRequest', - ticket: 'Ticket' + request: OrgRequest, + ticket: Ticket ) -> BytesIO: """ Creates a PDF representation of the ticket. It is sensible to the diff --git a/src/onegov/org/redirects.py b/src/onegov/org/redirects.py index 3c194a62e6..1254000d14 100644 --- a/src/onegov/org/redirects.py +++ b/src/onegov/org/redirects.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.org import OrgApp from onegov.core.redirect import Redirect diff --git a/src/onegov/org/request.py b/src/onegov/org/request.py index a2f9adb841..10fb391780 100644 --- a/src/onegov/org/request.py +++ b/src/onegov/org/request.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from functools import cached_property from onegov.core.orm import orm_cached from onegov.core.request import CoreRequest @@ -25,11 +27,11 @@ class PageMeta(NamedTuple): published: bool is_visible_on_homepage: bool | None path: str - children: tuple['PageMeta', ...] + children: tuple[PageMeta, ...] def link( self, - request: 'OrgRequest', + request: OrgRequest, variables: dict[str, Any] | None = None, name: str = '', ) -> str: @@ -47,7 +49,7 @@ def link( class OrgRequest(CoreRequest): if TYPE_CHECKING: - app: 'OrgApp' + app: OrgApp @cached_property def is_manager(self) -> bool: @@ -147,7 +149,7 @@ def mtan_access_limit_exceeded(self) -> bool: # if we already accessed this url we are also still fine return self.mtan_accesses.by_url(self.path_url) is None - def auto_accept(self, ticket: 'Ticket') -> bool: + def auto_accept(self, ticket: Ticket) -> bool: if self.app.org.ticket_auto_accept_style == 'role': roles = self.app.org.ticket_auto_accept_roles if not roles: @@ -222,9 +224,9 @@ def include(page: PageMeta) -> bool: def homepage_pages(self) -> dict[int, list[PageMeta]]: def visit_topics( - pages: 'Iterable[PageMeta]', + pages: Iterable[PageMeta], root_id: int | None = None - ) -> 'Generator[tuple[int, PageMeta]]': + ) -> Generator[tuple[int, PageMeta]]: for page in pages: if page.type != 'topic': continue diff --git a/src/onegov/org/security.py b/src/onegov/org/security.py index d47c1179d1..214ff6c52e 100644 --- a/src/onegov/org/security.py +++ b/src/onegov/org/security.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from onegov.org.app import OrgApp from onegov.org.models import Export from onegov.ticket import Ticket @@ -21,7 +23,7 @@ def has_export_permission_not_logged_in( @OrgApp.permission_rule(model=Export, permission=object) def has_export_permissions_logged_in( app: OrgApp, - identity: 'Identity', + identity: Identity, model: Export, permission: object ) -> bool: @@ -31,7 +33,7 @@ def has_export_permissions_logged_in( @OrgApp.permission_rule(model=Ticket, permission=object) def has_permission_ticket( app: OrgApp, - identity: 'Identity', + identity: Identity, model: Ticket, permission: object ) -> bool: diff --git a/src/onegov/org/templates/imageset.pt b/src/onegov/org/templates/imageset.pt index a6074919e3..2ea9bd91c8 100644 --- a/src/onegov/org/templates/imageset.pt +++ b/src/onegov/org/templates/imageset.pt @@ -10,7 +10,7 @@ This album does not contain any images yet.

-
+

${image.note} @@ -22,7 +22,7 @@