diff options
Diffstat (limited to 'extra')
29 files changed, 525 insertions, 0 deletions
diff --git a/extra/elogind/elogind.initd b/extra/elogind/elogind.initd new file mode 100644 index 0000000..0c22ca9 --- /dev/null +++ b/extra/elogind/elogind.initd @@ -0,0 +1,23 @@ +#!/sbin/openrc-run +supervisor=supervise-daemon + +name="System login manager" +description="System service that manages user logins" +description_reload="Reload configuration without exiting" + +command=/usr/libexec/elogind/elogind + +depend() { + need dbus + + # Make sure we start before any other display manager + before display-manager +} + +extra_started_commands="reload" + +reload() { + ebegin "Reloading configuration" + $supervisor $RC_SVCNAME --signal HUP + eend $? +} diff --git a/extra/elogind/id-nobody.patch b/extra/elogind/id-nobody.patch new file mode 100644 index 0000000..5e9e5cd --- /dev/null +++ b/extra/elogind/id-nobody.patch @@ -0,0 +1,13 @@ +--- a/src/basic/user-util.h ++++ b/src/basic/user-util.h +@@ -70,8 +70,8 @@ int take_etc_passwd_lock(const char *root); + #define UID_INVALID ((uid_t) -1) + #define GID_INVALID ((gid_t) -1) + +-#define UID_NOBODY ((uid_t) 65534U) +-#define GID_NOBODY ((gid_t) 65534U) ++#define UID_NOBODY ((uid_t) 99U) ++#define GID_NOBODY ((gid_t) 99U) + + #define ETC_PASSWD_LOCK_PATH "/etc/.pwd.lock" + diff --git a/extra/elogind/mips.patch b/extra/elogind/mips.patch new file mode 100644 index 0000000..ca1c097 --- /dev/null +++ b/extra/elogind/mips.patch @@ -0,0 +1,11 @@ +--- a/src/basic/missing_syscall.h 2021-01-15 08:12:02.000000000 +0100 ++++ b/src/basic/missing_syscall.h 2021-02-24 07:20:32.026355819 +0100 +@@ -11,7 +11,7 @@ + #include <sys/wait.h> + #include <unistd.h> + +-#ifdef ARCH_MIPS ++#if defined(_MIPSEL) || defined(_MIPSEB) + #include <asm/sgidefs.h> + #endif + diff --git a/extra/elogind/ppc64-bad-tuple.patch b/extra/elogind/ppc64-bad-tuple.patch new file mode 100644 index 0000000..f6237ff --- /dev/null +++ b/extra/elogind/ppc64-bad-tuple.patch @@ -0,0 +1,25 @@ +From 0ce8ef86e8bfc872b40bc090fea9873fa1f51836 Mon Sep 17 00:00:00 2001 +From: q66 <daniel@octaforge.org> +Date: Thu, 21 Jan 2021 22:22:28 +0100 +Subject: [PATCH] fix ppc64 arch tuple + +--- + src/basic/architecture.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git src/basic/architecture.h src/basic/architecture.h +index 620b522..3ea6e52 100644 +--- a/src/basic/architecture.h ++++ b/src/basic/architecture.h +@@ -77,7 +77,7 @@ int uname_architecture(void); + #elif defined(__powerpc64__) + # if __BYTE_ORDER == __BIG_ENDIAN + # define native_architecture() ARCHITECTURE_PPC64 +-# define LIB_ARCH_TUPLE "ppc64-linux-gnu" ++# define LIB_ARCH_TUPLE "powerpc64-linux-gnu" + # define SECONDARY_ARCHITECTURE ARCHITECTURE_PPC + # else + # define native_architecture() ARCHITECTURE_PPC64_LE +-- +2.30.0 + diff --git a/extra/elogind/ppcle.patch b/extra/elogind/ppcle.patch new file mode 100644 index 0000000..b986b0f --- /dev/null +++ b/extra/elogind/ppcle.patch @@ -0,0 +1,25 @@ +From 836f3efb84a703b3594906572a54616d25cecf5e Mon Sep 17 00:00:00 2001 +From: q66 <daniel@octaforge.org> +Date: Thu, 21 Jan 2021 21:59:12 +0100 +Subject: [PATCH] add ppcle arch tuple + +--- + src/basic/architecture.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git src/basic/architecture.h src/basic/architecture.h +index 620b522..afdff7a 100644 +--- a/src/basic/architecture.h ++++ b/src/basic/architecture.h +@@ -94,7 +94,7 @@ int uname_architecture(void); + # endif + # else + # define native_architecture() ARCHITECTURE_PPC_LE +-# error "Missing LIB_ARCH_TUPLE for PPCLE" ++# define LIB_ARCH_TUPLE "powerpcle-linux-gnu" + # endif + #elif defined(__ia64__) + # define native_architecture() ARCHITECTURE_IA64 +-- +2.30.0 + diff --git a/extra/mesa/0001-radeonsi-On-Aarch64-force-persistent-buffers-to-GTT.patch b/extra/mesa/0001-radeonsi-On-Aarch64-force-persistent-buffers-to-GTT.patch new file mode 100644 index 0000000..ea855f6 --- /dev/null +++ b/extra/mesa/0001-radeonsi-On-Aarch64-force-persistent-buffers-to-GTT.patch @@ -0,0 +1,38 @@ +From d72aa8ae74ffb7329003f9f23ffa05833af951ab Mon Sep 17 00:00:00 2001 +From: Jon Nettleton <jon@solid-run.com> +Date: Fri, 14 Aug 2020 13:36:08 +0200 +Subject: [PATCH] radeonsi: On Aarch64 force persistent buffers to GTT + +This fixes a glamore corruption issue on the HoneyComb and by +internet reports should also fix problems seen on Huaweii +Kunpeng hardware. + +The root cause of the corruption needs to be worked out, but +this patch also adds a noticable performance improvement. The +aquarium webgl demo under chromium increases from 39-49 FPS +when 5000 fish being rendered is selected. Glmark scores also +improve by ~200 with no specific tests showing any regression. + +Signed-off-by: Jon Nettleton <jon@solid-run.com> +--- + src/gallium/drivers/radeonsi/si_buffer.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/gallium/drivers/radeonsi/si_buffer.c b/src/gallium/drivers/radeonsi/si_buffer.c +index 6b58aebee2d..c9e983367a0 100644 +--- a/src/gallium/drivers/radeonsi/si_buffer.c ++++ b/src/gallium/drivers/radeonsi/si_buffer.c +@@ -151,6 +151,11 @@ void si_init_resource_fields(struct si_screen *sscreen, struct si_resource *res, + */ + if (!sscreen->info.kernel_flushes_hdp_before_ib || !sscreen->info.is_amdgpu) + res->domains = RADEON_DOMAIN_GTT; ++ ++#if defined(PIPE_ARCH_AARCH64) ++ if (size <= 1024 * 512) ++ res->domains = RADEON_DOMAIN_GTT; ++#endif + } + + /* Tiled textures are unmappable. Always put them in VRAM. */ +-- +2.26.2 diff --git a/extra/mesa/add-use-elf-tls.patch b/extra/mesa/add-use-elf-tls.patch new file mode 100644 index 0000000..629c5ac --- /dev/null +++ b/extra/mesa/add-use-elf-tls.patch @@ -0,0 +1,29 @@ +diff --git a/meson.build b/meson.build +index e1e94e7..b355f94 100644 +--- a/meson.build ++++ b/meson.build +@@ -447,7 +447,9 @@ endif + + # Android uses emutls for versions <= P/28. For USE_ELF_TLS we need ELF TLS. + use_elf_tls = false +-if (not ['freebsd', 'openbsd', 'haiku'].contains(host_machine.system()) and ++with_use_elf_tls = get_option('use-elf-tls') ++if with_use_elf_tls and ++ (not ['freebsd', 'openbsd', 'haiku'].contains(host_machine.system()) and + (not with_platform_android or get_option('platform-sdk-version') >= 29) and + (not with_platform_windows or not with_shared_glapi)) + pre_args += '-DUSE_ELF_TLS' +diff --git a/meson_options.txt b/meson_options.txt +index a7030ab..73bd28e 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -465,3 +465,9 @@ option( + value : true, + description : 'use msse2 flag for mingw x86. Default: true', + ) ++option( ++ 'use-elf-tls', ++ type : 'boolean', ++ value : false, ++ description : 'Build support for initial-exec TLS model' ++) diff --git a/extra/mesa/disable-rgb10-by-default.patch b/extra/mesa/disable-rgb10-by-default.patch new file mode 100644 index 0000000..6e1158b --- /dev/null +++ b/extra/mesa/disable-rgb10-by-default.patch @@ -0,0 +1,25 @@ +From b33c8b56abcc4837f96f7f106b108681858482e0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> +Date: Tue, 24 Apr 2018 09:46:41 +0200 +Subject: [PATCH] gallium: Disable rgb10 configs by default + +Applications tend to not handle rgb10 configs very well, so lets +disable it for now. + +https://bugzilla.redhat.com/show_bug.cgi?id=1560481 +--- + src/gallium/auxiliary/pipe-loader/driinfo_gallium.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h +index 3b630f7..b542e0c 100644 +--- a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h ++++ b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h +@@ -49,6 +49,6 @@ DRI_CONF_SECTION_MISCELLANEOUS + DRI_CONF_GLSL_ZERO_INIT(false) + DRI_CONF_VS_POSITION_ALWAYS_INVARIANT(false) + DRI_CONF_VS_POSITION_ALWAYS_PRECISE(false) +- DRI_CONF_ALLOW_RGB10_CONFIGS(true) ++ DRI_CONF_ALLOW_RGB10_CONFIGS(false) + DRI_CONF_FORCE_INTEGER_TEX_NEAREST(false) + DRI_CONF_SECTION_END diff --git a/extra/mesa/musl-fix-includes.patch b/extra/mesa/musl-fix-includes.patch new file mode 100644 index 0000000..8553d44 --- /dev/null +++ b/extra/mesa/musl-fix-includes.patch @@ -0,0 +1,13 @@ +diff --git a/src/util/rand_xor.c b/src/util/rand_xor.c +index 81b64f1ea71..14e6c9d27c3 100644 +--- a/src/util/rand_xor.c ++++ b/src/util/rand_xor.c +@@ -27,6 +27,8 @@ + #if !DETECT_OS_WINDOWS + #if defined(HAVE_GETRANDOM) + #include <sys/random.h> ++#include <sys/types.h> ++#include <sys/stat.h> + #endif + #include <unistd.h> + #include <fcntl.h> diff --git a/extra/pam/other.pamd b/extra/pam/other.pamd new file mode 100644 index 0000000..20bdb74 --- /dev/null +++ b/extra/pam/other.pamd @@ -0,0 +1,11 @@ + +auth required pam_warn.so +auth required pam_deny.so +account required pam_warn.so +account required pam_deny.so +password required pam_warn.so +password required pam_deny.so +session required pam_warn.so +session required pam_deny.so + + diff --git a/extra/pam/system-account.pamd b/extra/pam/system-account.pamd new file mode 100644 index 0000000..b36f26d --- /dev/null +++ b/extra/pam/system-account.pamd @@ -0,0 +1 @@ +account required pam_unix.so diff --git a/extra/pam/system-auth.pamd b/extra/pam/system-auth.pamd new file mode 100644 index 0000000..5f85baf --- /dev/null +++ b/extra/pam/system-auth.pamd @@ -0,0 +1,2 @@ +auth required pam_unix.so + diff --git a/extra/pam/system-password.pamd b/extra/pam/system-password.pamd new file mode 100644 index 0000000..56d5122 --- /dev/null +++ b/extra/pam/system-password.pamd @@ -0,0 +1,3 @@ +# basic PAM configuration for Alpine. + +password required pam_unix.so nullok md5 sha512 shadow try_first_pass diff --git a/extra/pam/system-session.pamd b/extra/pam/system-session.pamd new file mode 100644 index 0000000..5e25d29 --- /dev/null +++ b/extra/pam/system-session.pamd @@ -0,0 +1,3 @@ + +session required pam_unix.so + diff --git a/extra/shadow/chage.pamd b/extra/shadow/chage.pamd new file mode 100644 index 0000000..3f277f8 --- /dev/null +++ b/extra/shadow/chage.pamd @@ -0,0 +1,11 @@ +# Begin /etc/pam.d/chage + +# always allow root +auth sufficient pam_rootok.so + +# include system auth and account settings +auth include system-auth +account include system-account + +# End /etc/pam.d/chage + diff --git a/extra/shadow/chpasswd.pamd b/extra/shadow/chpasswd.pamd new file mode 100644 index 0000000..81afbee --- /dev/null +++ b/extra/shadow/chpasswd.pamd @@ -0,0 +1,12 @@ +# Begin /etc/pam.d/newusers + +# always allow root +auth sufficient pam_rootok.so + +# include system auth and account settings +auth include system-auth +account include system-account +password include system-password + +# End /etc/pam.d/newusers + diff --git a/extra/shadow/login.pamd b/extra/shadow/login.pamd new file mode 100644 index 0000000..c6410c1 --- /dev/null +++ b/extra/shadow/login.pamd @@ -0,0 +1,46 @@ +# Begin /etc/pam.d/login + +# Set failure delay before next prompt to 3 seconds +auth optional pam_faildelay.so delay=3000000 + +# Check to make sure that the user is allowed to login +auth requisite pam_nologin.so + +# Check to make sure that root is allowed to login +# Disabled by default. You will need to create /etc/securetty +# file for this module to function. See man 5 securetty. +#auth required pam_securetty.so + +# Additional group memberships - disabled by default +#auth optional pam_group.so + +# include system auth settings +auth include system-auth + +# check access for the user +account required pam_access.so + +# include system account settings +account include system-account + +# Set default environment variables for the user +session required pam_env.so + +# Set resource limits for the user +session required pam_limits.so + +# Display date of last login - Disabled by default +#session optional pam_lastlog.so + +# Display the message of the day - Disabled by default +#session optional pam_motd.so + +# Check user's mail - Disabled by default +#session optional pam_mail.so standard quiet + +# include system session and password settings +session include system-session +password include system-password + +# End /etc/pam.d/login + diff --git a/extra/shadow/newusers.pamd b/extra/shadow/newusers.pamd new file mode 100644 index 0000000..57f5cfa --- /dev/null +++ b/extra/shadow/newusers.pamd @@ -0,0 +1,12 @@ +# Begin /etc/pam.d/chpasswd + +# always allow root +auth sufficient pam_rootok.so + +# include system auth and account settings +auth include system-auth +account include system-account +password include system-password + +# End /etc/pam.d/chpasswd + diff --git a/extra/shadow/passwd.pamd b/extra/shadow/passwd.pamd new file mode 100644 index 0000000..83459e3 --- /dev/null +++ b/extra/shadow/passwd.pamd @@ -0,0 +1,6 @@ +# Begin /etc/pam.d/passwd + +password include system-password + +# End /etc/pam.d/passwd + diff --git a/extra/shadow/su.pamd b/extra/shadow/su.pamd new file mode 100644 index 0000000..ca6ab90 --- /dev/null +++ b/extra/shadow/su.pamd @@ -0,0 +1,27 @@ +# Begin /etc/pam.d/su + +# always allow root +auth sufficient pam_rootok.so + +# Allow users in the wheel group to execute su without a password +# disabled by default +#auth sufficient pam_wheel.so trust use_uid + +# include system auth settings +auth include system-auth + +# limit su to users in the wheel group +# disabled by default +#auth required pam_wheel.so use_uid + +# include system account settings +account include system-account + +# Set default environment variables for the service user +session required pam_env.so + +# include system session settings +session include system-session + +# End /etc/pam.d/su + diff --git a/extra/strace/disable-fortify.patch b/extra/strace/disable-fortify.patch new file mode 100644 index 0000000..26b2978 --- /dev/null +++ b/extra/strace/disable-fortify.patch @@ -0,0 +1,39 @@ +Subject: [PATCH] don't use fortify-headers on netlink test sources +From: A. Wilcox <AWilcox@Wilcox-Tech.com> + +We can't use fortify-headers on netlink tests because it tests what happens +when a buffer overrun occurs. + +--- strace-4.18/tests/netlink_protocol.c.old 2017-07-05 07:08:09.000000000 +0000 ++++ strace-4.18/tests/netlink_protocol.c 2017-08-17 01:09:45.822502012 +0000 +@@ -28,6 +28,8 @@ + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#define _FORTIFY_SOURCE 0 ++ + #include "tests.h" + + #ifdef HAVE_SYS_XATTR_H +--- strace-4.18/tests/netlink_sock_diag.c.old 2017-07-05 07:08:09.000000000 +0000 ++++ strace-4.18/tests/netlink_sock_diag.c 2017-08-17 01:10:00.935807300 +0000 +@@ -27,6 +27,8 @@ + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#define _FORTIFY_SOURCE 0 ++ + #include "tests.h" + #include <stdio.h> + #include <string.h> +--- strace-4.18/tests/nlattr.c.old 2017-07-05 07:08:09.000000000 +0000 ++++ strace-4.18/tests/nlattr.c 2017-08-17 01:10:11.862453682 +0000 +@@ -28,6 +28,8 @@ + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#define _FORTIFY_SOURCE 0 ++ + #include "tests.h" + + #include <stdio.h> diff --git a/extra/strace/nlattr-fix.patch b/extra/strace/nlattr-fix.patch new file mode 100644 index 0000000..6d480fa --- /dev/null +++ b/extra/strace/nlattr-fix.patch @@ -0,0 +1,21 @@ +--- strace-4.18/tests/nlattr.c.old 2017-07-05 07:08:09.000000000 +0000 ++++ strace-4.18/tests/nlattr.c 2017-08-17 00:25:26.734218699 +0000 +@@ -61,7 +61,7 @@ + }; + struct msg *msg; + struct nlattr *nla; +- unsigned int msg_len; ++ uint32_t msg_len; + long rc; + + /* fetch fail: len < sizeof(struct nlattr) */ +@@ -259,7 +259,7 @@ + }; + struct msg *msg; + struct nlattr *nla; +- unsigned int msg_len; ++ uint32_t msg_len; + long rc; + + msg_len = NLMSG_SPACE(sizeof(msg->udm)) + sizeof(*nla); + diff --git a/extra/utmps/btmpd.initd b/extra/utmps/btmpd.initd new file mode 100644 index 0000000..b9acc72 --- /dev/null +++ b/extra/utmps/btmpd.initd @@ -0,0 +1,24 @@ +#!/sbin/openrc-run +# Copyright 2020-2021 Laurent Bercot for Alpine Linux +# Distributed under the terms of the ISC License. +# +name=btmpd +description="utmps daemon for the btmp service" + +command=/bin/s6-ipcserver +command_args="/run/utmps/.btmpd-socket utmps-wtmpd btmp" +command_user=utmp +command_background=yes +directory=/var/log/btmpd +pidfile=/run/utmps/btmpd.pid + +depend() { + need localmount utmp-prepare + after bootmisc + before networking +} + +start_pre() { + checkpath -d -o utmp:utmp -m 0755 /run/utmps + checkpath -d -o utmp:utmp -m 2755 /var/log/btmpd +} diff --git a/extra/utmps/btmpd.logrotate b/extra/utmps/btmpd.logrotate new file mode 100644 index 0000000..b681d90 --- /dev/null +++ b/extra/utmps/btmpd.logrotate @@ -0,0 +1,6 @@ +/var/log/btmpd/btmp { + missingok + monthly + create 0644 utmp utmp + rotate 3 +} diff --git a/extra/utmps/utmp-init.initd b/extra/utmps/utmp-init.initd new file mode 100644 index 0000000..acb4dbe --- /dev/null +++ b/extra/utmps/utmp-init.initd @@ -0,0 +1,21 @@ +#!/sbin/openrc-run +# Copyright 2020-2022 Laurent Bercot for Alpine Linux +# Distributed under the terms of the ISC License. +# +description="clearing and initialization of the utmp database" + +depend() { + need utmp-prepare utmpd wtmpd + before networking + after clock +} + +start() { + # Create an empty utmp file + checkpath -F -f -m 0644 -o utmp:utmp /run/utmps/utmp + + # Write the initial records as sysvinit/busybox init would do. + # 20018 = 256 * 'N' + '2'. Don't ask. + utmps-write -t 2000 -uw -l reboot -p 0 -h "$(uname -r)" -- '~~' BOOT_TIME '~' + utmps-write -t 2000 -uw -l runlevel -p 20018 -h "$(uname -r)" -- '~~' RUN_LVL '~' +} diff --git a/extra/utmps/utmp-prepare.initd b/extra/utmps/utmp-prepare.initd new file mode 100644 index 0000000..9f61249 --- /dev/null +++ b/extra/utmps/utmp-prepare.initd @@ -0,0 +1,25 @@ +#!/sbin/openrc-run +# Copyright 2020-2022 Laurent Bercot for Alpine Linux +# Distributed under the terms of the ISC License. +# +description="preparation of the utmp databases" + +depend() { + before networking + after clock +} + +start() { + if ! test -L /var/log/utmp || test "$(readlink /var/log/utmp)" != /run/utmps/utmp ; then + rm -f /var/log/utmp + ln -s /run/utmps/utmp /var/log/utmp + fi + if ! test -L /var/log/wtmp || test "$(readlink /var/log/wtmp)" != wtmpd/wtmp ; then + rm -f /var/log/wtmp + ln -s wtmpd/wtmp /var/log/wtmp + fi + if ! test -L /var/log/btmp || test "$(readlink /var/log/btmp)" != btmpd/btmp ; then + rm -f /var/log/btmp + ln -s btmpd/btmp /var/log/btmp + fi +} diff --git a/extra/utmps/utmpd.initd b/extra/utmps/utmpd.initd new file mode 100644 index 0000000..d04c6b9 --- /dev/null +++ b/extra/utmps/utmpd.initd @@ -0,0 +1,23 @@ +#!/sbin/openrc-run +# Copyright 2020-2021 Laurent Bercot for Alpine Linux +# Distributed under the terms of the ISC License. +# +name="utmpd" +description="utmps daemon for the utmp service" + +command=/bin/s6-ipcserver +command_args="/run/utmps/.utmpd-socket utmps-utmpd" +command_user=utmp +command_background=yes +directory=/run/utmps +pidfile=/run/utmps/utmpd.pid + +depend() { + need utmp-prepare + after bootmisc + before networking +} + +start_pre() { + checkpath -d -o utmp:utmp -m 0755 /run/utmps +} diff --git a/extra/utmps/wtmpd.initd b/extra/utmps/wtmpd.initd new file mode 100644 index 0000000..8d3f624 --- /dev/null +++ b/extra/utmps/wtmpd.initd @@ -0,0 +1,24 @@ +#!/sbin/openrc-run +# Copyright 2020-2021 Laurent Bercot for Alpine Linux +# Distributed under the terms of the ISC License. +# +name=wtmpd +description="utmps daemon for the wtmp service" + +command=/bin/s6-ipcserver +command_args="/run/utmps/.wtmpd-socket utmps-wtmpd wtmp" +command_user=utmp +command_background=yes +directory=/var/log/wtmpd +pidfile=/run/utmps/wtmpd.pid + +depend() { + need localmount utmp-prepare + after bootmisc + before networking +} + +start_pre() { + checkpath -d -o utmp:utmp -m 0755 /run/utmps + checkpath -d -o utmp:utmp -m 2755 /var/log/wtmpd +} diff --git a/extra/utmps/wtmpd.logrotate b/extra/utmps/wtmpd.logrotate new file mode 100644 index 0000000..bb23536 --- /dev/null +++ b/extra/utmps/wtmpd.logrotate @@ -0,0 +1,6 @@ +/var/log/wtmpd/wtmp { + missingok + monthly + create 0644 utmp utmp + rotate 3 +} |