summaryrefslogtreecommitdiff
path: root/dev-python/django
diff options
context:
space:
mode:
Diffstat (limited to 'dev-python/django')
-rw-r--r--dev-python/django/Manifest4
-rw-r--r--dev-python/django/django-4.0.5.ebuild110
-rw-r--r--dev-python/django/files/django-4.0.5-py311.patch218
3 files changed, 332 insertions, 0 deletions
diff --git a/dev-python/django/Manifest b/dev-python/django/Manifest
index 3c5f1dbb617f..8f660b0714a9 100644
--- a/dev-python/django/Manifest
+++ b/dev-python/django/Manifest
@@ -1,13 +1,17 @@
AUX django-2.0.7-bashcomp.patch 1507 BLAKE2B 8aeb494087dbccffc69ad43f370e791d9fbfb1908d45f55d5f8be01ec0f3af6b2aff591da84a06c0858fecd44180579a4647d622ef57d8235ccb4b3b80fd3a2a SHA512 5a3867b8e4f2fafe4c53a741d41e8c6e8e28a55463f7d8007afd669a04daa8b93f911e4ef8d5ad38ba300558f21ac8090b00337d0c0bfb93b2aea73a179334a4
AUX django-3.1-bashcomp.patch 2085 BLAKE2B 36a0aa4d3413f13089ac104f5d3f98ecbb152a9a5a35f8c1ff2e5ffc9824153b0ac89f1cbca76c31a1afefde471e4d6ed801e405551b25cb31da89c20f3019cc SHA512 82dceede4292bad6e3e4966a6dba01bd2bbc7db494fce592e25dc4a64236485d88d8ad67b247239a80f8fe96dff054d20afea6f48a5518b67cf88404d399e61c
AUX django-4.0-bashcomp.patch 2021 BLAKE2B f04c83b500a92ea8ef9609225191e38a41b3349a295beca8f8575ab05395d0cf37e1aefe295004b11c1bcf34cce9074ac7d274034cb50e1ae43e2fcb5d6952b2 SHA512 2215dca4120023b0fd839738bd602443c49e9adaa98d182bc74081ebe70613649c2dc11e2b5f6242701dceac25755adb8605774895091360b56ed1195a7e629e
+AUX django-4.0.5-py311.patch 9279 BLAKE2B 3082f4f9da3f127807402a55655b059019787143dd8c2cb14b1a27d2fbf66464179c2f08381284340fccb4e6bc1c25a1e36291a0dd8cbd83c754ee1f78d220b8 SHA512 d48f29fa5fe9e434a4220825d1592a03a0667d956db4e6c4119e74f91524b8d02b295a5a600516a993adc2dd3e1f5ca4bde83acd8a6a8e0838382116d2703a28
DIST Django-2.2.28.checksum.txt 2554 BLAKE2B 23421008f45040be56c417fb4d31ab8cb72d6d6fb59f12e53de1a7947ffed3a290908a49e7ce08bbb155380472daed93b33c2e90580d3bd0aa3d0d9190478bca SHA512 a7e4b2abf3f3ff79e6a0a55047afc6dcb97a2a27bdd6b25770ad60df3eaa4d260d332ef0b94e63971c500a313c2033127575510e871c5ec648bd045c04353aa1
DIST Django-2.2.28.tar.gz 9187543 BLAKE2B da6ae04b84a858a678b9740694cf1b638128b783da1aa8443c0e85ea3d7f71104e433de043ff7264575e2df36b6fea7275874ff04391b41eb70ba6c7c78306dc SHA512 228aec6ee8619ff3d0397ff867bd59352900fb95557bd02cfea594b3bc3f813b5bcd13f488b451b0ee79a4d52deab19c5e97aa40f1075ba06db72542d119228e
DIST Django-3.2.13.checksum.txt 2554 BLAKE2B 301d816685f6d97c4a18b4f9d015b063521a7e90a870f1c95ec37ebbc1d4e7311abfee7f7c4aafaa40932334d0eab68fc768dcf21acfffe1d098cabd71ea161a SHA512 ef4a5d0fb8e885cbc2854a4b9b2380dec1cec0e8f6d9bc54179354eb6170755bd6f02268ad5bdc81fdea9d30022422462b0b14894ccc0f37d2e7288aeda83abb
DIST Django-3.2.13.tar.gz 9813985 BLAKE2B eb8319cc225491fc71f719d2eef6daa05114a97b1302093a0cf0f77bb2a51f398e7a034df7aa52c6a64e9796b9cc66b127fccee810cb38508506ba4cd121cfbf SHA512 08f056b18bc04b95d6705cf70c2ecc5be0c1324e0b38582991b907ed5977c4e3d35417ccf4ec06c2436a718e3aae007b015f0d40dd94ce5cfb129a54cceb6578
DIST Django-4.0.4.checksum.txt 2545 BLAKE2B d82f7b01f49f2b37de3cfd9eb8738e4af69c8eda0c3ed2b6d80a5f876989f36a9335640c5cd5916dcc682fcbf5453c299cb8b3f52e05f2d29413a4c75d274cbc SHA512 9889e086f35192432084fd2ae1104c316e63fa2ab0d34f6954d5eb98b810b5f2e10861a4136c480b54178d2a5453a36f3b893c7720a92f35b44cd578902a8bf9
DIST Django-4.0.4.tar.gz 10388499 BLAKE2B f839b343bf5c2f83810f2bb22e93a91b18ccc30754589fef2931ebdf29d4600a3bf5493f9e977a3b647097c3a379ea1ef4e0e25366efb54082bc0f43ed00485f SHA512 75ecf5991763237297b458f546d245a25f62272f7013364783aea19469586fa54ce94a16323ac9a6d6b81097f8e962ea7a20f26c7afd8acda842812409215bb1
+DIST Django-4.0.5.checksum.txt 2549 BLAKE2B e0aae25d6e9b15eddc9f6be566d611d03b3cd2aa97020b99372eebbc5183e2f04f27bfc9c1faa9f4b5ec0e4da453a5812a8c8afd7dbb61c10424c458c81bf453 SHA512 45c628253a530df210c94b7c2e8493faaa5eecd68c1f84c4d61936f0f85d590ddc96d64be0313a6353435bed884fde6f6cf0bd54dc04d361dac093f259c5927b
+DIST Django-4.0.5.tar.gz 10410720 BLAKE2B 43c8000a54829d639a63a7a17067368b3c6fbda483eae374d4e7f561a3bd3490b754de888e597514f706b1843c8dae2f78453f0efc8eb9a335874993eac44e8f SHA512 915dd5f853544dcd9f85e7d11f50d3f8c34eaf4a6819ec76178bec9466feaf2b386f044fdeebec6bd88366917b8feb6e2512d45b8996c8906326205d4f449f90
EBUILD django-2.2.28.ebuild 2883 BLAKE2B 97d88776ac645e43e9a2d4055d723db2574578f177bef090c856fa75e4e86a17be92349319f511c1453717a4a2bbf58b8338420193403ec86d2c49d702e2b324 SHA512 836d41ece537fd64a773f41718c4aa4c5954da1aa8ac291418088d7970af05f812538be03f1dc7c29341c728c57ee3e73f5ad59aa50cc862a54e30abfe3b8e53
EBUILD django-3.2.13.ebuild 3050 BLAKE2B da552703a81abf12dc9f104268237438fcc8b9003a9d4789706ee2c812799aef24e4476039cd64bb65c7821f844138e22220006ea14c1475cf3d1705babc6298 SHA512 59e9aa4a66d7b804578fab30b0db04ad2f07d482c07260bfdec986c921d321e4a79b03c046b877a2ffb7d0bc204f0799d4f2557abdc01560879db2c75d68f536
EBUILD django-4.0.4.ebuild 2974 BLAKE2B 1462faba7a068fffa1aad96c8a0466121d69fe796642095701146b9fdc8e0944dc11ba51a86f7c83625297dad1d5c9809507e0bb565f394733fbfb16bec5c67d SHA512 9669c2ce74724c6a5c85e26f6c9214110baa7e9cff10521c258e5e7ec7dbd4721e250b67318637af27cecde4278acf6658d5f8c456047a332930d46ceee684f4
+EBUILD django-4.0.5.ebuild 3018 BLAKE2B e24afde03de90a8a8cb43d1eb44993502f8acb1142dd9d361dd681365d1edfc0d5eb5f41ab8d0fc9751c2143120e2c4fab296f410d57acd72f7b4b38d86841c0 SHA512 8d35e894c2aea6e344c6e1186d4f733e9528ca144a6d7ff650a001b162d0ec64c5925ec0b19188452bc7cd89dc66c3a9cad81204e4d0b45d61cff42a7f2b3150
MISC metadata.xml 400 BLAKE2B 6b3414ac734f078d90c82b44edd2f9f70e494e98da8a3d874d18006ae5e0eb5f7060b98b402094d6045e800bf525586f2566e6f554a8b2999cce37bdcc5472a0 SHA512 1cf0bb6ef93da3abbd1a66878462b1b8672a9b8fccd7f968b427e429caa6ecf30cb703a6060d621ccad1ba77b927d2b0e632b04b0a47975918ccbfcc5f2b85f7
diff --git a/dev-python/django/django-4.0.5.ebuild b/dev-python/django/django-4.0.5.ebuild
new file mode 100644
index 000000000000..16e1a7824c10
--- /dev/null
+++ b/dev-python/django/django-4.0.5.ebuild
@@ -0,0 +1,110 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DISTUTILS_USE_PEP517=setuptools
+PYTHON_COMPAT=( python3_{8..11} )
+PYTHON_REQ_USE='sqlite?,threads(+)'
+
+inherit bash-completion-r1 distutils-r1 optfeature verify-sig
+
+MY_P=${P^}
+DESCRIPTION="High-level Python web framework"
+HOMEPAGE="
+ https://www.djangoproject.com/
+ https://pypi.org/project/Django/
+"
+SRC_URI="
+ https://media.djangoproject.com/releases/$(ver_cut 1-2)/${MY_P}.tar.gz
+ verify-sig? ( https://media.djangoproject.com/pgp/${MY_P}.checksum.txt )
+"
+S="${WORKDIR}/${MY_P}"
+
+LICENSE="BSD"
+# admin fonts: Roboto (media-fonts/roboto)
+LICENSE+=" Apache-2.0"
+# admin icons, jquery, xregexp.js
+LICENSE+=" MIT"
+SLOT="0"
+KEYWORDS="~amd64 ~arm ~arm64 ~ppc ~ppc64 ~riscv ~sparc ~x86 ~x64-macos"
+IUSE="doc sqlite test"
+RESTRICT="!test? ( test )"
+
+RDEPEND="
+ >=dev-python/asgiref-3.4.1[${PYTHON_USEDEP}]
+ >=dev-python/sqlparse-0.2.2[${PYTHON_USEDEP}]
+ $(python_gen_cond_dep '
+ dev-python/backports-zoneinfo[${PYTHON_USEDEP}]
+ ' 3.8)
+"
+BDEPEND="
+ test? (
+ $(python_gen_impl_dep sqlite)
+ ${RDEPEND}
+ dev-python/docutils[${PYTHON_USEDEP}]
+ dev-python/jinja[${PYTHON_USEDEP}]
+ dev-python/numpy[${PYTHON_USEDEP}]
+ dev-python/pillow[webp,${PYTHON_USEDEP}]
+ dev-python/pyyaml[${PYTHON_USEDEP}]
+ dev-python/selenium[${PYTHON_USEDEP}]
+ dev-python/tblib[${PYTHON_USEDEP}]
+ sys-devel/gettext
+ !!<dev-python/ipython-7.21.0-r1
+ !!=dev-python/ipython-7.22.0-r0
+ )
+ verify-sig? ( >=sec-keys/openpgp-keys-django-20201201 )
+"
+
+PATCHES=(
+ "${FILESDIR}"/${PN}-4.0-bashcomp.patch
+ "${FILESDIR}"/django-4.0.5-py311.patch
+)
+
+distutils_enable_sphinx docs --no-autodoc
+
+VERIFY_SIG_OPENPGP_KEY_PATH=${BROOT}/usr/share/openpgp-keys/django.asc
+
+src_unpack() {
+ if use verify-sig; then
+ cd "${DISTDIR}" || die
+ verify-sig_verify_signed_checksums \
+ "${MY_P}.checksum.txt" sha256 "${MY_P}.tar.gz"
+ cd "${WORKDIR}" || die
+ fi
+
+ default
+}
+
+src_prepare() {
+ # TODO: this suddenly started failing
+ sed -i -e 's:test_custom_fields:_&:' tests/inspectdb/tests.py || die
+
+ distutils-r1_src_prepare
+}
+
+python_test() {
+ # Tests have non-standard assumptions about PYTHONPATH,
+ # and don't work with ${BUILD_DIR}/lib.
+ PYTHONPATH=. "${EPYTHON}" tests/runtests.py --settings=test_sqlite -v2 ||
+ die "Tests fail with ${EPYTHON}"
+}
+
+python_install_all() {
+ newbashcomp extras/django_bash_completion ${PN}-admin
+ bashcomp_alias ${PN}-admin django-admin.py
+
+ distutils-r1_python_install_all
+}
+
+pkg_postinst() {
+ optfeature_header "Additional Backend support can be enabled via:"
+ optfeature "MySQL backend support" dev-python/mysqlclient
+ optfeature "PostgreSQL backend support" dev-python/psycopg:2
+ optfeature_header
+ optfeature "GEO Django" "sci-libs/gdal[geos]"
+ optfeature "Memcached support" dev-python/pylibmc dev-python/python-memcached
+ optfeature "ImageField Support" dev-python/pillow
+ optfeature "Password encryption" dev-python/bcrypt
+ optfeature "High-level abstractions for Django forms" dev-python/django-formtools
+}
diff --git a/dev-python/django/files/django-4.0.5-py311.patch b/dev-python/django/files/django-4.0.5-py311.patch
new file mode 100644
index 000000000000..d566db006574
--- /dev/null
+++ b/dev-python/django/files/django-4.0.5-py311.patch
@@ -0,0 +1,218 @@
+From 3d022e13bcc1de5162ba7198c856bf27c03d4f37 Mon Sep 17 00:00:00 2001
+From: David Smith <39445562+smithdc1@users.noreply.github.com>
+Date: Sat, 19 Feb 2022 19:36:01 +0000
+Subject: [PATCH 1/3] Refs #33173 -- Fixed MailTests.test_backend_arg() on
+ Windows and Python 3.11+.
+
+---
+ django/utils/version.py | 1 +
+ tests/mail/tests.py | 3 ++-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/django/utils/version.py b/django/utils/version.py
+index 77f13833cb..8f4ab2bcfa 100644
+--- a/django/utils/version.py
++++ b/django/utils/version.py
+@@ -15,6 +15,7 @@ PY37 = sys.version_info >= (3, 7)
+ PY38 = sys.version_info >= (3, 8)
+ PY39 = sys.version_info >= (3, 9)
+ PY310 = sys.version_info >= (3, 10)
++PY311 = sys.version_info >= (3, 11)
+
+
+ def get_version(version=None):
+diff --git a/tests/mail/tests.py b/tests/mail/tests.py
+index 51e26cc6be..183a0c0ab1 100644
+--- a/tests/mail/tests.py
++++ b/tests/mail/tests.py
+@@ -29,6 +29,7 @@ from django.core.mail.message import BadHeaderError, sanitize_address
+ from django.test import SimpleTestCase, override_settings
+ from django.test.utils import requires_tz_support
+ from django.utils.translation import gettext_lazy
++from django.utils.version import PY311
+
+ try:
+ from aiosmtpd.controller import Controller
+@@ -790,7 +791,7 @@ class MailTests(HeadersCheckMixin, SimpleTestCase):
+ filebased.EmailBackend,
+ )
+
+- if sys.platform == "win32":
++ if sys.platform == "win32" and not PY311:
+ msg = (
+ "_getfullpathname: path should be string, bytes or os.PathLike, not "
+ "object"
+--
+2.35.1
+
+From 4d548dce8fb280ed7be63e9818c316fe5f0ee154 Mon Sep 17 00:00:00 2001
+From: Mariusz Felisiak <felisiak.mariusz@gmail.com>
+Date: Thu, 7 Apr 2022 07:02:21 +0200
+Subject: [PATCH 2/3] Refs #33173 -- Fixed test_runner/test_utils tests on
+ Python 3.11+.
+
+Python 3.11 uses fully qualified test name in unittest output. See
+https://github.com/python/cpython/commit/755be9b1505af591b9f2ee424a6525b6c2b65ce9
+---
+ tests/test_runner/test_debug_sql.py | 14 +++++++++-----
+ tests/test_runner/test_parallel.py | 5 ++++-
+ tests/test_utils/tests.py | 13 +++++++++----
+ 3 files changed, 22 insertions(+), 10 deletions(-)
+
+diff --git a/tests/test_runner/test_debug_sql.py b/tests/test_runner/test_debug_sql.py
+index 9957295f01..d45d8cb4ba 100644
+--- a/tests/test_runner/test_debug_sql.py
++++ b/tests/test_runner/test_debug_sql.py
+@@ -4,6 +4,7 @@ from io import StringIO
+ from django.db import connection
+ from django.test import TestCase
+ from django.test.runner import DiscoverRunner
++from django.utils.version import PY311
+
+ from .models import Person
+
+@@ -109,14 +110,17 @@ class TestDebugSQL(unittest.TestCase):
+ ),
+ ]
+
++ # Python 3.11 uses fully qualified test name in the output.
++ method_name = ".runTest" if PY311 else ""
++ test_class_path = "test_runner.test_debug_sql.TestDebugSQL"
+ verbose_expected_outputs = [
+- "runTest (test_runner.test_debug_sql.TestDebugSQL.FailingTest) ... FAIL",
+- "runTest (test_runner.test_debug_sql.TestDebugSQL.ErrorTest) ... ERROR",
+- "runTest (test_runner.test_debug_sql.TestDebugSQL.PassingTest) ... ok",
++ f"runTest ({test_class_path}.FailingTest{method_name}) ... FAIL",
++ f"runTest ({test_class_path}.ErrorTest{method_name}) ... ERROR",
++ f"runTest ({test_class_path}.PassingTest{method_name}) ... ok",
+ # If there are errors/failures in subtests but not in test itself,
+ # the status is not written. That behavior comes from Python.
+- "runTest (test_runner.test_debug_sql.TestDebugSQL.FailingSubTest) ...",
+- "runTest (test_runner.test_debug_sql.TestDebugSQL.ErrorSubTest) ...",
++ f"runTest ({test_class_path}.FailingSubTest{method_name}) ...",
++ f"runTest ({test_class_path}.ErrorSubTest{method_name}) ...",
+ (
+ """SELECT COUNT(*) AS "__count" """
+ """FROM "test_runner_person" WHERE """
+diff --git a/tests/test_runner/test_parallel.py b/tests/test_runner/test_parallel.py
+index ca208f6a48..a2f68d3512 100644
+--- a/tests/test_runner/test_parallel.py
++++ b/tests/test_runner/test_parallel.py
+@@ -4,6 +4,7 @@ import unittest
+
+ from django.test import SimpleTestCase
+ from django.test.runner import RemoteTestResult
++from django.utils.version import PY311
+
+ try:
+ import tblib.pickling_support
+@@ -125,7 +126,9 @@ class RemoteTestResultTest(SimpleTestCase):
+ self.assertEqual(event[0], "addSubTest")
+ self.assertEqual(
+ str(event[2]),
+- "dummy_test (test_runner.test_parallel.SampleFailingSubtest) (index=0)",
++ "dummy_test (test_runner.test_parallel.SampleFailingSubtest%s) (index=0)"
++ # Python 3.11 uses fully qualified test name in the output.
++ % (".dummy_test" if PY311 else ""),
+ )
+ self.assertEqual(repr(event[3][1]), "AssertionError('0 != 1')")
+
+diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py
+index b21c83585b..3b17da1c13 100644
+--- a/tests/test_utils/tests.py
++++ b/tests/test_utils/tests.py
+@@ -47,6 +47,7 @@ from django.test.utils import (
+ from django.urls import NoReverseMatch, path, reverse, reverse_lazy
+ from django.utils.deprecation import RemovedInDjango41Warning
+ from django.utils.log import DEFAULT_LOGGING
++from django.utils.version import PY311
+
+ from .models import Car, Person, PossessedCar
+ from .views import empty_response
+@@ -99,9 +100,11 @@ class SkippingTestCase(SimpleTestCase):
+ SkipTestCase("test_foo").test_foo,
+ ValueError,
+ "skipUnlessDBFeature cannot be used on test_foo (test_utils.tests."
+- "SkippingTestCase.test_skip_unless_db_feature.<locals>.SkipTestCase) "
++ "SkippingTestCase.test_skip_unless_db_feature.<locals>.SkipTestCase%s) "
+ "as SkippingTestCase.test_skip_unless_db_feature.<locals>.SkipTestCase "
+- "doesn't allow queries against the 'default' database.",
++ "doesn't allow queries against the 'default' database."
++ # Python 3.11 uses fully qualified test name in the output.
++ % (".test_foo" if PY311 else ""),
+ )
+
+ def test_skip_if_db_feature(self):
+@@ -144,9 +147,11 @@ class SkippingTestCase(SimpleTestCase):
+ SkipTestCase("test_foo").test_foo,
+ ValueError,
+ "skipIfDBFeature cannot be used on test_foo (test_utils.tests."
+- "SkippingTestCase.test_skip_if_db_feature.<locals>.SkipTestCase) "
++ "SkippingTestCase.test_skip_if_db_feature.<locals>.SkipTestCase%s) "
+ "as SkippingTestCase.test_skip_if_db_feature.<locals>.SkipTestCase "
+- "doesn't allow queries against the 'default' database.",
++ "doesn't allow queries against the 'default' database."
++ # Python 3.11 uses fully qualified test name in the output.
++ % (".test_foo" if PY311 else ""),
+ )
+
+
+--
+2.35.1
+
+From 2037b6b40a4250daaf3fa85f489fab34536c4f3a Mon Sep 17 00:00:00 2001
+From: Mariusz Felisiak <felisiak.mariusz@gmail.com>
+Date: Mon, 9 May 2022 10:38:11 +0200
+Subject: [PATCH 3/3] Refs #33173 -- Fixed test_dateparse tests on Python
+ 3.11+.
+
+date/datetime/time.fromisoformat() support any valid ISO 8601 format
+in Python 3.11+, see https://github.com/python/cpython/issues/80010.
+---
+ tests/utils_tests/test_dateparse.py | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tests/utils_tests/test_dateparse.py b/tests/utils_tests/test_dateparse.py
+index 8683811636..3f04a8a49c 100644
+--- a/tests/utils_tests/test_dateparse.py
++++ b/tests/utils_tests/test_dateparse.py
+@@ -8,6 +8,7 @@ from django.utils.dateparse import (
+ parse_time,
+ )
+ from django.utils.timezone import get_fixed_timezone
++from django.utils.version import PY311
+
+
+ class DateParseTests(unittest.TestCase):
+@@ -15,14 +16,18 @@ class DateParseTests(unittest.TestCase):
+ # Valid inputs
+ self.assertEqual(parse_date("2012-04-23"), date(2012, 4, 23))
+ self.assertEqual(parse_date("2012-4-9"), date(2012, 4, 9))
++ if PY311:
++ self.assertEqual(parse_date("20120423"), date(2012, 4, 23))
+ # Invalid inputs
+- self.assertIsNone(parse_date("20120423"))
++ self.assertIsNone(parse_date("2012423"))
+ with self.assertRaises(ValueError):
+ parse_date("2012-04-56")
+
+ def test_parse_time(self):
+ # Valid inputs
+ self.assertEqual(parse_time("09:15:00"), time(9, 15))
++ if PY311:
++ self.assertEqual(parse_time("091500"), time(9, 15))
+ self.assertEqual(parse_time("10:10"), time(10, 10))
+ self.assertEqual(parse_time("10:20:30.400"), time(10, 20, 30, 400000))
+ self.assertEqual(parse_time("10:20:30,400"), time(10, 20, 30, 400000))
+@@ -35,7 +40,7 @@ class DateParseTests(unittest.TestCase):
+ self.assertIsNone(parse_time("00:05:23+"))
+ self.assertIsNone(parse_time("00:05:23+25:00"))
+ self.assertIsNone(parse_time("4:18:101"))
+- self.assertIsNone(parse_time("091500"))
++ self.assertIsNone(parse_time("91500"))
+ with self.assertRaises(ValueError):
+ parse_time("09:15:90")
+
+--
+2.35.1
+