From 7f93d81ce63f970bf6845c9a548ebdc628779ecf Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Tue, 18 Dec 2012 21:05:27 +0100 Subject: lpm: Use charger with optimized graphics and lpm.rc Signed-off-by: Paul Kocialkowski --- BoardConfigCommon.mk | 5 + device_base.mk | 4 + lpm.rc | 277 +- recovery/graphics.c | 97 +- res/charger/LICENSE | 2 + res/charger/battery_0.png | Bin 0 -> 6510 bytes res/charger/battery_1.png | Bin 0 -> 6760 bytes res/charger/battery_2.png | Bin 0 -> 6759 bytes res/charger/battery_3.png | Bin 0 -> 6750 bytes res/charger/battery_4.png | Bin 0 -> 6654 bytes res/charger/battery_5.png | Bin 0 -> 6473 bytes res/charger/battery_charge.png | Bin 0 -> 8478 bytes res/charger/battery_fail.png | Bin 0 -> 8485 bytes res/charger/charger.svg | 6671 ++++++++++++++++++++++++++++++++++++++++ 14 files changed, 6770 insertions(+), 286 deletions(-) create mode 100644 res/charger/LICENSE create mode 100644 res/charger/battery_0.png create mode 100644 res/charger/battery_1.png create mode 100644 res/charger/battery_2.png create mode 100644 res/charger/battery_3.png create mode 100644 res/charger/battery_4.png create mode 100644 res/charger/battery_5.png create mode 100644 res/charger/battery_charge.png create mode 100644 res/charger/battery_fail.png create mode 100644 res/charger/charger.svg diff --git a/BoardConfigCommon.mk b/BoardConfigCommon.mk index 755344f..c911ea7 100644 --- a/BoardConfigCommon.mk +++ b/BoardConfigCommon.mk @@ -82,6 +82,11 @@ WIFI_DRIVER_FW_PATH_STA := "/vendor/firmware/fw_bcmdhd.bin" WIFI_DRIVER_FW_PATH_P2P := "/vendor/firmware/fw_bcmdhd_p2p.bin" WIFI_DRIVER_FW_PATH_AP := "/vendor/firmware/fw_bcmdhd_apsta.bin" +# Charging mode +BOARD_CHARGING_MODE_BOOTING_LPM := /sys/class/power_supply/battery/charging_mode_booting +BOARD_BATTERY_DEVICE_NAME := "battery" +BOARD_CHARGER_RES := device/samsung/aries-common/res/charger + # Vold BOARD_VOLD_EMMC_SHARES_DEV_MAJOR := true TARGET_USE_CUSTOM_LUN_FILE_PATH := "/sys/devices/platform/s3c-usbgadget/gadget/lun%d/file" diff --git a/device_base.mk b/device_base.mk index 3dc4ce7..cb340a3 100644 --- a/device_base.mk +++ b/device_base.mk @@ -107,6 +107,10 @@ PRODUCT_PACKAGES += libsamsung-ril \ libsamsung-ril-client \ ipc-modemctrl +# Charger +PRODUCT_PACKAGES += \ + charger \ + charger_res_images # Libs PRODUCT_PACKAGES += \ diff --git a/lpm.rc b/lpm.rc index 84a6e9a..fc195ec 100644 --- a/lpm.rc +++ b/lpm.rc @@ -2,281 +2,60 @@ on early-init start ueventd on init - -sysclktz 0 - -loglevel 9 - -# setup the global environment export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin export LD_LIBRARY_PATH /vendor/lib:/system/lib - export ANDROID_BOOTLOGO 1 export ANDROID_ROOT /system - export ANDROID_ASSETS /system/app export ANDROID_DATA /data - export EXTERNAL_STORAGE /mnt/sdcard + export ANDROID_CACHE /cache export SECONDARY_STORAGE /mnt/emmc - export ASEC_MOUNTPOINT /mnt/asec - export LOOP_MOUNTPOINT /mnt/obb + export EXTERNAL_STORAGE /mnt/sdcard symlink /system/etc /etc + mkdir /mnt 0775 root system -# Backward compatibility - symlink /sys/kernel/debug /d - -# Right now vendor lives on the same filesystem as system, -# but someday that may change. - symlink /system/vendor /vendor - -# create temp folder for recovery - mkdir /tmp - -# create mountpoints - mkdir /sdcard 0000 system system - mkdir /emmc 0000 system system - -# for emergencyboot - symlink /sdcard /mnt/sdcard - -# Create cgroup mount point for cpu accounting - mkdir /acct - mount cgroup none /acct cpuacct - mkdir /acct/uid mkdir /system - mkdir /data 0771 system system - mkdir /cache 0770 system cache - mkdir /config 0500 root root - mkdir /efs - - # Directory for putting things only root should see. - mkdir /mnt/secure 0700 root root - - # Directory for staging bindmounts - mkdir /mnt/secure/staging 0700 root root - - # Directory-target for where the secure container - # imagefile directory will be bind-mounted - mkdir /mnt/secure/asec 0700 root root - - # Secure container public mount points. - mkdir /mnt/asec 0700 root system - mount tmpfs tmpfs /mnt/asec mode=0755,gid=1000 - - # Filesystem image public mount points. - mkdir /mnt/obb 0700 root system - mount tmpfs tmpfs /mnt/obb mode=0755,gid=1000 - - write /proc/sys/kernel/panic_on_oops 1 - write /proc/sys/kernel/hung_task_timeout_secs 0 - write /proc/cpu/alignment 4 - write /proc/sys/kernel/sched_latency_ns 10000000 - write /proc/sys/kernel/sched_wakeup_granularity_ns 2000000 - write /proc/sys/kernel/sched_compat_yield 1 - write /proc/sys/kernel/sched_child_runs_first 0 - -# Create cgroup mount points for process groups - mkdir /dev/cpuctl - mount cgroup none /dev/cpuctl cpu - chown system system /dev/cpuctl - chown system system /dev/cpuctl/tasks - chmod 0777 /dev/cpuctl/tasks - write /dev/cpuctl/cpu.shares 1024 - - mkdir /dev/cpuctl/fg_boost - chown system system /dev/cpuctl/fg_boost/tasks - chmod 0777 /dev/cpuctl/fg_boost/tasks - write /dev/cpuctl/fg_boost/cpu.shares 1024 - - mkdir /dev/cpuctl/bg_non_interactive - chown system system /dev/cpuctl/bg_non_interactive/tasks - chmod 0777 /dev/cpuctl/bg_non_interactive/tasks - # 5.0 % - write /dev/cpuctl/bg_non_interactive/cpu.shares 52 - -on fs -# mount mtd partitions - # Mount /system rw first to give the filesystem a chance to save a checkpoint - mount yaffs2 mtd@system /system - #mount yaffs2 mtd@cache /cache - #mount ext4 /dev/block/mmcblk0p2 /data nosuid nodev noatime nodiratime noauto_da_alloc - #mount yaffs2 mtd@datadata /datadata - -on post-fs - # once everything is setup, no need to modify / - #mount rootfs rootfs / ro remount - - # We chown/chmod /data again so because mount is run as root + defaults - chown system system /data - chmod 0771 /data - - # Create dump dir and collect dumps. - # Do this before we mount cache so eventually we can use cache for - # storing dumps on platforms which do not have a dedicated dump partition. - - mkdir /data/dontpanic - chown root log /data/dontpanic - chmod 0750 /data/dontpanic - - # Collect apanic data, free resources and re-arm trigger - copy /proc/apanic_console /data/dontpanic/apanic_console - chown root log /data/dontpanic/apanic_console - chmod 0640 /data/dontpanic/apanic_console - - copy /proc/apanic_threads /data/dontpanic/apanic_threads - chown root log /data/dontpanic/apanic_threads - chmod 0640 /data/dontpanic/apanic_threads - - write /proc/apanic_console 1 - - # Same reason as /data above - chown system cache /cache - chmod 0770 /cache - - # This may have been created by the recovery system with odd permissions - chown system cache /cache/recovery - chmod 0770 /cache/recovery - - #change permissions on vmallocinfo so we can grab it from bugreports - chown root log /proc/vmallocinfo - chmod 0440 /proc/vmallocinfo - - #change permissions on kmsg & sysrq-trigger so bugreports can grab kthread stacks - chown root system /proc/kmsg - chmod 0440 /proc/kmsg - chown root system /proc/sysrq-trigger - chmod 0220 /proc/sysrq-trigger - -# create basic filesystem structure - mkdir /data/misc 01771 system misc - mkdir /data/misc/bluetoothd 0770 bluetooth bluetooth - mkdir /data/misc/bluetooth 0770 system system - mkdir /data/misc/keystore 0700 keystore keystore - mkdir /data/misc/vpn 0770 system system - mkdir /data/misc/systemkeys 0700 system system - mkdir /data/misc/vpn/profiles 0770 system system - # give system access to wpa_supplicant.conf for backup and restore - mkdir /data/misc/wifi 0770 wifi wifi - chmod 0770 /data/misc/wifi - chmod 0660 /data/misc/wifi/wpa_supplicant.conf - mkdir /data/local 0771 shell shell - mkdir /data/local/tmp 0771 shell shell - mkdir /data/data 0771 system system - mkdir /data/app-private 0771 system system - mkdir /data/app 0771 system system - mkdir /data/property 0700 root root - - # create dalvik-cache and double-check the perms - mkdir /data/dalvik-cache 0771 system system - chown system system /data/dalvik-cache - chmod 0771 /data/dalvik-cache - - # create the lost+found directories, so as to enforce our permissions - mkdir /data/lost+found 0770 - mkdir /cache/lost+found 0770 + mkdir /tmp + mkdir /mnt 0775 root root - # double check the perms, in case lost+found already exists, and set owner - chown root root /data/lost+found - chmod 0770 /data/lost+found - chown root root /cache/lost+found - chmod 0770 /cache/lost+found on boot -# basic network init ifup lo hostname localhost domainname localdomain -# set RLIMIT_NICE to allow priorities from 19 to -20 - setrlimit 13 40 40 - - # Set init its forked children's oom_adj. - write /proc/1/oom_adj -16 - - # Tweak background writeout - write /proc/sys/vm/dirty_expire_centisecs 200 - write /proc/sys/vm/dirty_background_ratio 5 - - # Permissions for System Server and daemons. - chown radio system /sys/android_power/state - chown radio system /sys/android_power/request_state - chown radio system /sys/android_power/acquire_full_wake_lock - chown radio system /sys/android_power/acquire_partial_wake_lock - chown radio system /sys/android_power/release_wake_lock - chown radio system /sys/power/state - chown radio system /sys/power/wake_lock - chown radio system /sys/power/wake_unlock - chmod 0660 /sys/power/state - chmod 0660 /sys/power/wake_lock - chmod 0660 /sys/power/wake_unlock - chown system system /sys/class/timed_output/vibrator/enable - chown system system /sys/class/leds/keyboard-backlight/brightness - chown system system /sys/class/leds/lcd-backlight/brightness - chown system system /sys/class/leds/button-backlight/brightness - chown system system /sys/class/leds/jogball-backlight/brightness - chown system system /sys/class/leds/red/brightness - chown system system /sys/class/leds/green/brightness - chown system system /sys/class/leds/blue/brightness - chown system system /sys/class/leds/red/device/grpfreq - chown system system /sys/class/leds/red/device/grppwm - chown system system /sys/class/leds/red/device/blink - chown system system /sys/class/leds/red/brightness - chown system system /sys/class/leds/green/brightness - chown system system /sys/class/leds/blue/brightness - chown system system /sys/class/leds/red/device/grpfreq - chown system system /sys/class/leds/red/device/grppwm - chown system system /sys/class/leds/red/device/blink - chown system system /sys/class/timed_output/vibrator/enable - chown system system /sys/module/sco/parameters/disable_esco - chown system system /sys/kernel/ipv4/tcp_wmem_min - chown system system /sys/kernel/ipv4/tcp_wmem_def - chown system system /sys/kernel/ipv4/tcp_wmem_max - chown system system /sys/kernel/ipv4/tcp_rmem_min - chown system system /sys/kernel/ipv4/tcp_rmem_def - chown system system /sys/kernel/ipv4/tcp_rmem_max - chown root radio /proc/cmdline - -# Define TCP buffer sizes for various networks -# ReadMin, ReadInitial, ReadMax, WriteMin, WriteInitial, WriteMax, - setprop net.tcp.buffersize.default 4096,87380,110208,4096,16384,110208 - setprop net.tcp.buffersize.wifi 4095,87380,110208,4096,16384,110208 - setprop net.tcp.buffersize.umts 4094,87380,110208,4096,16384,110208 - setprop net.tcp.buffersize.edge 4093,26280,35040,4096,16384,35040 - setprop net.tcp.buffersize.gprs 4092,8760,11680,4096,8760,11680 - class_start default -## Daemon processes to be run by init. -## service ueventd /sbin/ueventd + class core critical -service console /sbin/sh +service console /system/bin/sh + class core console - disabled - user shell - group log - -on property:ro.secure=0 - start console -service playlpm /system/bin/playlpm - user root - oneshot - -service lpmkey /system/bin/charging_mode - user root - oneshot - -# adbd is controlled by the persist.service.adb.enable system property service adbd /sbin/adbd disabled -# adbd on at boot in emulator -on property:ro.kernel.qemu=1 - start adbd +service charger /charger + class default + user root -on property:persist.service.adb.enable=1 +# Always start adbd on userdebug and eng builds +# In recovery, always run adbd as root. +on property:ro.debuggable=1 + write /sys/class/android_usb/android0/enable 0 + write /sys/class/android_usb/android0/idVendor 04e8 + write /sys/class/android_usb/android0/idProduct 6860 + write /sys/class/android_usb/android0/functions adb + write /sys/class/android_usb/android0/enable 1 + write /sys/class/android_usb/android0/iManufacturer $ro.product.manufacturer + write /sys/class/android_usb/android0/iProduct $ro.product.model + write /sys/class/android_usb/android0/iSerial $ro.serialno start adbd + setprop service.adb.root 1 -on property:persist.service.adb.enable=0 - stop adbd +# Restart adbd so it can run as root +on property:service.adb.root=1 + write /sys/class/android_usb/android0/enable 0 + restart adbd + write /sys/class/android_usb/android0/enable 1 diff --git a/recovery/graphics.c b/recovery/graphics.c index 87e4e29..6d60b27 100644 --- a/recovery/graphics.c +++ b/recovery/graphics.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include @@ -29,14 +30,17 @@ #include -#ifndef BOARD_LDPI_RECOVERY - #include "font_10x18.h" +#ifdef BOARD_USE_CUSTOM_RECOVERY_FONT +#include BOARD_USE_CUSTOM_RECOVERY_FONT #else - #include "font_7x16.h" +#include "font_10x18.h" #endif #include "minui.h" +#define PIXEL_FORMAT GGL_PIXEL_FORMAT_BGRA_8888 +#define PIXEL_SIZE 4 + typedef struct { GGLSurface texture; unsigned cwidth; @@ -55,11 +59,11 @@ static int gr_fb_fd = -1; static int gr_vt_fd = -1; static struct fb_var_screeninfo vi; +static struct fb_fix_screeninfo fi; static int get_framebuffer(GGLSurface *fb) { int fd; - struct fb_fix_screeninfo fi; void *bits; fd = open("/dev/graphics/fb0", O_RDWR); @@ -68,13 +72,48 @@ static int get_framebuffer(GGLSurface *fb) return -1; } - if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) { + if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) { perror("failed to get fb0 info"); close(fd); return -1; } - if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) { + vi.bits_per_pixel = PIXEL_SIZE * 8; + if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_BGRA_8888) { + vi.red.offset = 8; + vi.red.length = 8; + vi.green.offset = 16; + vi.green.length = 8; + vi.blue.offset = 24; + vi.blue.length = 8; + vi.transp.offset = 0; + vi.transp.length = 8; + } else if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_RGBX_8888) { + vi.red.offset = 24; + vi.red.length = 8; + vi.green.offset = 16; + vi.green.length = 8; + vi.blue.offset = 8; + vi.blue.length = 8; + vi.transp.offset = 0; + vi.transp.length = 8; + } else { /* RGB565*/ + vi.red.offset = 11; + vi.red.length = 5; + vi.green.offset = 5; + vi.green.length = 6; + vi.blue.offset = 0; + vi.blue.length = 5; + vi.transp.offset = 0; + vi.transp.length = 0; + } + if (ioctl(fd, FBIOPUT_VSCREENINFO, &vi) < 0) { + perror("failed to put fb0 info"); + close(fd); + return -1; + } + + if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) { perror("failed to get fb0 info"); close(fd); return -1; @@ -90,29 +129,20 @@ static int get_framebuffer(GGLSurface *fb) fb->version = sizeof(*fb); fb->width = vi.xres; fb->height = vi.yres; -#ifdef BOARD_HAS_JANKY_BACKBUFFER - fb->stride = fi.line_length/2; -#else - fb->stride = vi.xres; -#endif + fb->stride = fi.line_length/PIXEL_SIZE; fb->data = bits; - fb->format = GGL_PIXEL_FORMAT_RGB_565; - memset(fb->data, 0, vi.yres * vi.xres * 2); + fb->format = PIXEL_FORMAT; + memset(fb->data, 0, vi.yres * fi.line_length); fb++; fb->version = sizeof(*fb); fb->width = vi.xres; fb->height = vi.yres; -#ifdef BOARD_HAS_JANKY_BACKBUFFER - fb->stride = fi.line_length/2; + fb->stride = fi.line_length/PIXEL_SIZE; fb->data = (void*) (((unsigned) bits) + vi.yres * fi.line_length); -#else - fb->stride = vi.xres; - fb->data = (void*) (((unsigned) bits) + vi.yres * vi.xres * 2); -#endif - fb->format = GGL_PIXEL_FORMAT_RGB_565; - memset(fb->data, 0, vi.yres * vi.xres * 2); + fb->format = PIXEL_FORMAT; + memset(fb->data, 0, vi.yres * fi.line_length); return fd; } @@ -121,17 +151,17 @@ static void get_memory_surface(GGLSurface* ms) { ms->version = sizeof(*ms); ms->width = vi.xres; ms->height = vi.yres; - ms->stride = vi.xres; - ms->data = malloc(vi.xres * vi.yres * 2); - ms->format = GGL_PIXEL_FORMAT_RGB_565; + ms->stride = fi.line_length/PIXEL_SIZE; + ms->data = malloc(fi.line_length * vi.yres); + ms->format = PIXEL_FORMAT; } static void set_active_framebuffer(unsigned n) { if (n > 1) return; - vi.yres_virtual = vi.yres * 2; + vi.yres_virtual = vi.yres * PIXEL_SIZE; vi.yoffset = n * vi.yres; - vi.bits_per_pixel = 16; + vi.bits_per_pixel = PIXEL_SIZE * 8; if (ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) { perror("active fb swap failed"); } @@ -144,20 +174,10 @@ void gr_flip(void) /* swap front and back buffers */ gr_active_fb = (gr_active_fb + 1) & 1; -#ifdef BOARD_HAS_FLIPPED_SCREEN - /* flip buffer 180 degrees for devices with physicaly inverted screens */ - unsigned int i; - for (i = 1; i < (vi.xres * vi.yres); i++) { - unsigned short tmp = gr_mem_surface.data[i]; - gr_mem_surface.data[i] = gr_mem_surface.data[(vi.xres * vi.yres * 2) - i]; - gr_mem_surface.data[(vi.xres * vi.yres * 2) - i] = tmp; - } -#endif - /* copy data from the in-memory surface to the buffer we're about * to make active. */ memcpy(gr_framebuffer[gr_active_fb].data, gr_mem_surface.data, - vi.xres * vi.yres * 2); + fi.line_length * vi.yres); /* inform the display driver */ set_active_framebuffer(gr_active_fb); @@ -313,6 +333,9 @@ int gr_init(void) gl->enable(gl, GGL_BLEND); gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA); + gr_fb_blank(true); + gr_fb_blank(false); + return 0; } diff --git a/res/charger/LICENSE b/res/charger/LICENSE new file mode 100644 index 0000000..91dc99c --- /dev/null +++ b/res/charger/LICENSE @@ -0,0 +1,2 @@ +Copyright: Copyright (C) 2012 Paul Kocialkowski +License: Creative Commons BY-SA 3.0 diff --git a/res/charger/battery_0.png b/res/charger/battery_0.png new file mode 100644 index 0000000..8d94eb8 Binary files /dev/null and b/res/charger/battery_0.png differ diff --git a/res/charger/battery_1.png b/res/charger/battery_1.png new file mode 100644 index 0000000..4c81941 Binary files /dev/null and b/res/charger/battery_1.png differ diff --git a/res/charger/battery_2.png b/res/charger/battery_2.png new file mode 100644 index 0000000..d59e0a9 Binary files /dev/null and b/res/charger/battery_2.png differ diff --git a/res/charger/battery_3.png b/res/charger/battery_3.png new file mode 100644 index 0000000..a46db2a Binary files /dev/null and b/res/charger/battery_3.png differ diff --git a/res/charger/battery_4.png b/res/charger/battery_4.png new file mode 100644 index 0000000..0ba8306 Binary files /dev/null and b/res/charger/battery_4.png differ diff --git a/res/charger/battery_5.png b/res/charger/battery_5.png new file mode 100644 index 0000000..41ead87 Binary files /dev/null and b/res/charger/battery_5.png differ diff --git a/res/charger/battery_charge.png b/res/charger/battery_charge.png new file mode 100644 index 0000000..550dc2f Binary files /dev/null and b/res/charger/battery_charge.png differ diff --git a/res/charger/battery_fail.png b/res/charger/battery_fail.png new file mode 100644 index 0000000..8c606de Binary files /dev/null and b/res/charger/battery_fail.png differ diff --git a/res/charger/charger.svg b/res/charger/charger.svg new file mode 100644 index 0000000..5541645 --- /dev/null +++ b/res/charger/charger.svg @@ -0,0 +1,6671 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + ? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.1